sdbus++: move enum definitions to common header

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: Idaba9c5669025b113b701c7abeb28692e0393b78
diff --git a/tools/sdbusplus/templates/interface.common.hpp.mako b/tools/sdbusplus/templates/interface.common.hpp.mako
index cc93d94..d33fe12 100644
--- a/tools/sdbusplus/templates/interface.common.hpp.mako
+++ b/tools/sdbusplus/templates/interface.common.hpp.mako
@@ -1,4 +1,13 @@
 #pragma once
+#include <algorithm>
+#include <array>
+#include <optional>
+#include <string>
+#include <string_view>
+#include <tuple>
+
+#include <sdbusplus/exception.hpp>
+#include <sdbusplus/message.hpp>
 
 namespace sdbusplus::common::${interface.cppNamespace()}
 {
@@ -6,6 +15,143 @@
 struct ${interface.classname}
 {
     static constexpr auto interface = "${interface.name}";
+
+    % for e in interface.enums:
+    enum class ${e.name}
+    {
+        % for v in e.values:
+        ${v.name},
+        % endfor
+    };
+    % 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.
+     *
+     *  @note Throws if string is not a valid mapping.
+     */
+    static ${e.name} convert${e.name}FromString(const std::string& s);
+
+    /** @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 or std::nullopt
+     */
+    static std::optional<${e.name}>
+        convertStringTo${e.name}(const std::string& s) noexcept;
+
+    /** @brief Convert an enum value to a string.
+     *  @param[in] e - The enum to convert to a string.
+     *  @return - The string conversion in the form of
+     *            "${interface.name}.<value name>"
+     */
+    static std::string convert${e.name}ToString(${e.name} e);
+    % endfor
 };
 
+% for e in interface.enums:
+/* Specialization of sdbusplus::common::convertForMessage
+ * for enum-type ${interface.classname}::${e.name}.
+ *
+ * This converts from the enum to a constant string representing the enum.
+ *
+ * @param[in] e - Enum value to convert.
+ * @return string representing the name for the enum value.
+ */
+inline std::string convertForMessage(${interface.classname}::${e.name} e)
+{
+    return ${interface.classname}::convert${e.name}ToString(e);
+}
+% endfor
+
+    % for e in interface.enums:
+
+namespace details
+{
+using namespace std::literals::string_view_literals;
+
+/** String to enum mapping for ${interface.classname}::${e.name} */
+inline constexpr std::array mapping${interface.classname}${e.name} = {
+    % for v in e.values:
+    std::make_tuple("${interface.name}.${e.name}.${v.name}"sv,
+                    ${interface.classname}::${e.name}::${v.name} ),
+    % endfor
+};
+} //  namespace details
+
+inline auto ${interface.classname}::convertStringTo${e.name}(const std::string& s) noexcept
+    -> std::optional<${e.name}>
+{
+    auto i = std::find_if(std::begin(details::mapping${interface.classname}${e.name}),
+                          std::end(details::mapping${interface.classname}${e.name}),
+                          [&s](auto& e){ return s == std::get<0>(e); } );
+
+    if (std::end(details::mapping${interface.classname}${e.name}) == i)
+    {
+        return std::nullopt;
+    }
+    else
+    {
+        return std::get<1>(*i);
+    }
+}
+
+inline auto ${interface.classname}::convert${e.name}FromString(const std::string& s) -> ${e.name}
+{
+    auto r = convertStringTo${e.name}(s);
+
+    if (!r)
+    {
+        throw sdbusplus::exception::InvalidEnumString();
+    }
+    else
+    {
+        return *r;
+    }
+}
+
+inline std::string ${interface.classname}::convert${e.name}ToString(
+    ${interface.classname}::${e.name} v)
+{
+    auto i = std::find_if(std::begin(details::mapping${interface.classname}${e.name}),
+                          std::end(details::mapping${interface.classname}${e.name}),
+                          [v](auto& e){ return v == std::get<1>(e); });
+
+    if (i == std::end(details::mapping${interface.classname}${e.name}))
+    {
+        throw std::invalid_argument(std::to_string(static_cast<int>(v)));
+    }
+    return std::string(std::get<0>(*i));
+}
+    % endfor
+
 } // sdbusplus::common::${interface.cppNamespace()}
+
+namespace sdbusplus::message::details
+{
+    % for e in interface.enums:
+template <>
+struct convert_from_string<common::${interface.cppNamespacedClass()}::${e.name}>
+{
+    static auto op(const std::string& value) noexcept
+    {
+        return common::${interface.cppNamespacedClass()}::
+            convertStringTo${e.name}(value);
+    }
+};
+
+template <>
+struct convert_to_string<common::${interface.cppNamespacedClass()}::${e.name}>
+{
+    static std::string
+        op(common::${interface.cppNamespacedClass()}::${e.name} value)
+    {
+        return common::${interface.cppNamespacedClass()}::
+            convert${e.name}ToString(value);
+    }
+};
+    % endfor
+} // namespace sdbusplus::message::details
diff --git a/tools/sdbusplus/templates/interface.server.cpp.mako b/tools/sdbusplus/templates/interface.server.cpp.mako
index ac698db..2f9af97 100644
--- a/tools/sdbusplus/templates/interface.server.cpp.mako
+++ b/tools/sdbusplus/templates/interface.server.cpp.mako
@@ -1,6 +1,4 @@
-#include <algorithm>
 #include <map>
-#include <sdbusplus/exception.hpp>
 #include <sdbusplus/sdbus.hpp>
 #include <sdbusplus/sdbuspp_support/server.hpp>
 #include <sdbusplus/server.hpp>
@@ -56,68 +54,7 @@
 }
 
     % endif
-    % for e in interface.enums:
 
-namespace
-{
-/** String to enum mapping for ${interface.classname}::${e.name} */
-static const std::tuple<const char*, ${interface.classname}::${e.name}> \
-mapping${interface.classname}${e.name}[] =
-        {
-        % for v in e.values:
-            std::make_tuple( "${interface.name}.${e.name}.${v.name}", \
-                ${interface.classname}::${e.name}::${v.name} ),
-        % endfor
-        };
-
-} // anonymous namespace
-
-auto ${interface.classname}::convertStringTo${e.name}(
-    const std::string& s) noexcept -> std::optional<${e.name}>
-{
-    auto i = std::find_if(
-            std::begin(mapping${interface.classname}${e.name}),
-            std::end(mapping${interface.classname}${e.name}),
-            [&s](auto& e){ return 0 == strcmp(s.c_str(), std::get<0>(e)); } );
-    if (std::end(mapping${interface.classname}${e.name}) == i)
-    {
-        return std::nullopt;
-    }
-    else
-    {
-        return std::get<1>(*i);
-    }
-}
-
-auto ${interface.classname}::convert${e.name}FromString(const std::string& s) ->
-    ${e.name}
-{
-    auto r = convertStringTo${e.name}(s);
-
-    if (!r)
-    {
-        throw sdbusplus::exception::InvalidEnumString();
-    }
-    else
-    {
-        return *r;
-    }
-}
-
-std::string ${interface.classname}::convert${e.name}ToString(
-    ${interface.classname}::${e.name} v)
-{
-    auto i = std::find_if(
-            std::begin(mapping${interface.classname}${e.name}),
-            std::end(mapping${interface.classname}${e.name}),
-            [v](auto& e){ return v == std::get<1>(e); });
-    if (i == std::end(mapping${interface.classname}${e.name}))
-    {
-        throw std::invalid_argument(std::to_string(static_cast<int>(v)));
-    }
-    return std::get<0>(*i);
-}
-    % endfor
 
 const vtable_t ${interface.classname}::_vtable[] = {
     vtable::start(),
diff --git a/tools/sdbusplus/templates/interface.server.hpp.mako b/tools/sdbusplus/templates/interface.server.hpp.mako
index ca20b2c..3ba5224 100644
--- a/tools/sdbusplus/templates/interface.server.hpp.mako
+++ b/tools/sdbusplus/templates/interface.server.hpp.mako
@@ -1,13 +1,11 @@
 #pragma once
 #include <limits>
 #include <map>
-#include <optional>
 #include <sdbusplus/sdbus.hpp>
 #include <sdbusplus/server.hpp>
 #include <sdbusplus/utility/dedup_variant.hpp>
 #include <string>
 #include <systemd/sd-bus.h>
-#include <tuple>
 
 % for m in interface.methods + interface.properties + interface.signals:
 ${ m.cpp_prototype(loader, interface=interface, ptype='callback-hpp-includes') }
@@ -51,15 +49,6 @@
                 bus, path, interface, _vtable, this),
             _intf(bus.getInterface()) {}
 
-    % for e in interface.enums:
-        enum class ${e.name}
-        {
-        % for v in e.values:
-            ${v.name},
-        % endfor
-        };
-    % endfor
-\
     % if interface.properties:
         using PropertiesVariant = sdbusplus::utility::dedup_variant_t<
                 ${",\n                ".join(sorted(setOfPropertyTypes()))}>;
@@ -118,31 +107,7 @@
         PropertiesVariant getPropertyByName(const std::string& _name);
 
     % endif
-    % 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.
-         *
-         *  @note Throws if string is not a valid mapping.
-         */
-        static ${e.name} convert${e.name}FromString(const std::string& s);
 
-        /** @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 or std::nullopt
-         */
-        static std::optional<${e.name}> convertStringTo${e.name}(
-                const std::string& s) noexcept;
-
-        /** @brief Convert an enum value to a string.
-         *  @param[in] e - The enum to convert to a string.
-         *  @return - The string conversion in the form of
-         *            "${interface.name}.<value name>"
-         */
-        static std::string convert${e.name}ToString(${e.name} e);
-    % endfor
 
         /** @brief Emit interface added */
         void emit_added()
@@ -193,21 +158,6 @@
 
 };
 
-    % for e in interface.enums:
-/* Specialization of sdbusplus::server::convertForMessage
- * for enum-type ${interface.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.
- */
-inline std::string convertForMessage(${interface.classname}::${e.name} e)
-{
-    return ${interface.classname}::convert${e.name}ToString(e);
-}
-    % endfor
-
 } // namespace sdbusplus::server::${interface.cppNamespace()}
 
 #ifndef SDBUSPP_REMOVE_DEPRECATED_NAMESPACE
@@ -215,36 +165,8 @@
 
 using sdbusplus::server::${interface.cppNamespacedClass()};
     % if interface.enums:
-using sdbusplus::server::${interface.cppNamespace()}::convertForMessage;
+using sdbusplus::common::${interface.cppNamespace()}::convertForMessage;
     % endif
 
 } // namespace sdbusplus::${interface.old_cppNamespace()}
 #endif
-
-namespace sdbusplus::message::details
-{
-    % for e in interface.enums:
-template <>
-struct convert_from_string<
-    server::${interface.cppNamespacedClass()}::${e.name}>
-{
-    static auto op(const std::string& value) noexcept
-    {
-        return server::
-            ${interface.cppNamespacedClass()}::convertStringTo${e.name}(value);
-    }
-};
-
-template <>
-struct convert_to_string<
-    server::${interface.cppNamespacedClass()}::${e.name}>
-{
-    static std::string op(
-        server::${interface.cppNamespacedClass()}::${e.name} value)
-    {
-        return server::
-            ${interface.cppNamespacedClass()}::convert${e.name}ToString(value);
-    }
-};
-    % endfor
-} // namespace sdbusplus::message::details