sdbusplus: message: append: add native enum support

Add support for appending enums directly into a sdbusplus message
and generate the required  helper functions in the interface server
templates.

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: Ib142482de90572e1bda2f3658f6aeec201c043de
diff --git a/sdbusplus/message/append.hpp b/sdbusplus/message/append.hpp
index 38a0b4a..d57fc9b 100644
--- a/sdbusplus/message/append.hpp
+++ b/sdbusplus/message/append.hpp
@@ -40,6 +40,15 @@
 namespace details
 {
 
+/** @brief Convert from a native type to a string.
+ *
+ *  Some C++ types cannot be represented directly on dbus, so we encode
+ *  them as strings.  Enums are the primary example of this.  This is a
+ *  template function prototype for the conversion to string functions.
+ */
+template <typename T>
+std::string convert_to_string(T) = delete;
+
 /** @struct can_append_multiple
  *  @brief Utility to identify C++ types that may not be grouped into a
  *         single sd_bus_message_append call and instead need special
@@ -155,9 +164,9 @@
      *  @param[in] m - sd_bus_message to append into.
      *  @param[in] t - The item to append.
      */
-    template <typename T,
-              typename = std::enable_if_t<std::is_same<S, Td<T>>::value>>
-    static void op(sdbusplus::SdBusInterface* intf, sd_bus_message* m, T&& t)
+    template <typename T>
+    static std::enable_if_t<std::is_same_v<S, Td<T>> && !std::is_enum_v<Td<T>>>
+        op(sdbusplus::SdBusInterface* intf, sd_bus_message* m, T&& t)
     {
         // For this default implementation, we need to ensure that only
         // basic types are used.
@@ -169,6 +178,14 @@
         intf->sd_bus_message_append_basic(m, dbusType,
                                           address_of(std::forward<T>(t)));
     }
+
+    template <typename T>
+    static std::enable_if_t<std::is_same_v<S, Td<T>> && std::is_enum_v<Td<T>>>
+        op(sdbusplus::SdBusInterface* intf, sd_bus_message* m, T&& t)
+    {
+        auto value = convert_to_string<Td<T>>(t);
+        sdbusplus::message::append(intf, m, value);
+    }
 };
 
 template <typename T>
diff --git a/tools/sdbusplus/templates/interface.mako.server.hpp b/tools/sdbusplus/templates/interface.mako.server.hpp
index 32119f9..ee6a31b 100644
--- a/tools/sdbusplus/templates/interface.mako.server.hpp
+++ b/tools/sdbusplus/templates/interface.mako.server.hpp
@@ -212,6 +212,13 @@
 {
     return ${cppNamespace()}::convert${e.name}FromString(value);
 }
+
+template <>
+inline std::string convert_to_string<${cppNamespace()}::${e.name}>(
+        ${cppNamespace()}::${e.name} value)
+{
+    return ${cppNamespace()}::convert${e.name}ToString(value);
+}
     % endfor
 } // namespace details
 } // namespace message