sdbus++: provide enum-string conversion functions

Change-Id: Ied31a6c11188fe3d0c909edb5c4bde3e337d96b3
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
diff --git a/tools/sdbusplus/templates/interface.mako.server.cpp b/tools/sdbusplus/templates/interface.mako.server.cpp
index b17ddda..efcc7c0 100644
--- a/tools/sdbusplus/templates/interface.mako.server.cpp
+++ b/tools/sdbusplus/templates/interface.mako.server.cpp
@@ -1,3 +1,4 @@
+#include <algorithm>
 #include <sdbusplus/server.hpp>
 #include <sdbusplus/exception.hpp>
 #include <${"/".join(interface.name.split('.') + [ 'server.hpp' ])}>
@@ -93,6 +94,49 @@
 }
     % endfor
 
+    % for e in interface.enums:
+
+namespace
+{
+/** String to enum mapping for ${classname}::${e.name} */
+static const std::tuple<const char*, ${classname}::${e.name}> \
+mapping${classname}${e.name}[] =
+        {
+        % for v in e.values:
+            std::make_tuple( "${interface.name}.${e.name}.${v.name}", \
+                ${classname}::${e.name}::${v.name} ),
+        % endfor
+        };
+
+} // anonymous namespace
+
+auto ${classname}::convert${e.name}FromString(std::string& s) ->
+        ${e.name}
+{
+    auto i = std::find_if(
+            std::begin(mapping${classname}${e.name}),
+            std::end(mapping${classname}${e.name}),
+            [&s](auto& e){ return 0 == strcmp(s.c_str(), std::get<0>(e)); } );
+    if (std::end(mapping${classname}${e.name}) == i)
+    {
+        throw sdbusplus::exception::InvalidEnumString();
+    }
+    else
+    {
+        return std::get<1>(*i);
+    }
+}
+
+std::string convertForMessage(${classname}::${e.name} v)
+{
+    auto i = std::find_if(
+            std::begin(mapping${classname}${e.name}),
+            std::end(mapping${classname}${e.name}),
+            [v](auto& e){ return v == std::get<1>(e); });
+    return std::get<0>(*i);
+}
+    % endfor
+
 const vtable::vtable_t ${classname}::_vtable[] = {
     vtable::start(),
     % for m in interface.methods:
diff --git a/tools/sdbusplus/templates/interface.mako.server.hpp b/tools/sdbusplus/templates/interface.mako.server.hpp
index 1fab15b..b7f8c71 100644
--- a/tools/sdbusplus/templates/interface.mako.server.hpp
+++ b/tools/sdbusplus/templates/interface.mako.server.hpp
@@ -64,6 +64,15 @@
 ${p.camelCase}(${p.cppTypeParam(interface.name)} value);
     % endfor
 
+    % for e in interface.enums:
+    /** @brief Convert a string to an appropriate enum value.
+     *  @param[in] s - The string to convert in the form of
+     *                 "${interface.name}.<value name>"
+     *  @return - The enum value.
+     */
+    static ${e.name} convert${e.name}FromString(std::string& s);
+    % endfor
+
     private:
     % for m in interface.methods:
 ${ m.cpp_prototype(loader, interface=interface, ptype='callback-header') }
@@ -100,6 +109,18 @@
 
 };
 
+    % for e in interface.enums:
+/* Specialization of sdbusplus::server::bindings::details::convertForMessage
+ * for enum-type ${classname}::${e.name}.
+ *
+ * This converts from the enum to a constant c-string representing the enum.
+ *
+ * @param[in] e - Enum value to convert.
+ * @return C-string representing the name for the enum value.
+ */
+std::string convertForMessage(${classname}::${e.name} e);
+    % endfor
+
 } // namespace server
     % for s in reversed(namespaces):
 } // namespace ${s}