sdbusplus: message: add type helpers for native enums

In order to be able to handle sdbus++ defined enums natively
with message read and append functions, we need some type
helpers so that the existing read/append frameworks know how
to deal with these types.

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: I3a5dbe0cde3366c6bb27e71ea965b3fe3059bc40
diff --git a/sdbusplus/message/append.hpp b/sdbusplus/message/append.hpp
index a7715ae..38a0b4a 100644
--- a/sdbusplus/message/append.hpp
+++ b/sdbusplus/message/append.hpp
@@ -48,10 +48,11 @@
  *  @tparam T - Type for identification.
  *
  *  User-defined types are expected to inherit from std::false_type.
- *
+ *  Enums are converted to strings, so must be done one at a time.
  */
 template <typename T, typename Enable = void>
-struct can_append_multiple : std::true_type
+struct can_append_multiple
+    : std::conditional_t<std::is_enum_v<T>, std::false_type, std::true_type>
 {
 };
 // unix_fd's int needs to be wrapped.
diff --git a/sdbusplus/message/read.hpp b/sdbusplus/message/read.hpp
index 5e2b899..31e3753 100644
--- a/sdbusplus/message/read.hpp
+++ b/sdbusplus/message/read.hpp
@@ -49,10 +49,12 @@
  *  @tparam T - Type for identification.
  *
  *  User-defined types are expected to inherit from std::false_type.
+ *  Enums are converted from strings, so must be done one at a time.
  *
  */
 template <typename T, typename Enable = void>
-struct can_read_multiple : std::true_type
+struct can_read_multiple
+    : std::conditional_t<std::is_enum_v<T>, std::false_type, std::true_type>
 {
 };
 // unix_fd's int needs to be wrapped
diff --git a/sdbusplus/message/types.hpp b/sdbusplus/message/types.hpp
index bd5946b..d00fb65 100644
--- a/sdbusplus/message/types.hpp
+++ b/sdbusplus/message/types.hpp
@@ -166,9 +166,14 @@
  *
  *  Struct must have a 'value' tuple containing the dbus type.  The default
  *  value is an empty tuple, which is used to indicate an unsupported type.
+ *
+ *  Enums are converted to strings on the dbus by some special conversion
+ *  routines.
  */
 template <typename T, typename Enable = void>
-struct type_id : public undefined_type_id
+struct type_id : public std::conditional_t<std::is_enum_v<T>,
+                                           tuple_type_id<SD_BUS_TYPE_STRING>,
+                                           undefined_type_id>
 {
 };
 // Specializations for built-in types.