utils: Fix bad conversion for enumerations

When an interface contains both a string and an enumeration (or multiple
of each), the variant visitor matches the wrong make specialization.

This is because a string is convertible to variant<string, enum, ...>.
Fix this by moving out all conversions from a string to the template
specialization that first checks if the string can be converted to
an enumeration.

This still leaves a hole where trying to set a fully-qualified
enumeration name to a string property will fail, but I am not sure what
to do about that within the current PIM framework.

Tested: Tested Notify with enumerations on interfaces that contain both
a string and an enumeration.

Signed-off-by: Santosh Puranik <santosh.puranik@in.ibm.com>
Change-Id: I58b93a225ccf0b6b70317b2a2050a4dfa2b1b6f7
diff --git a/utils.hpp b/utils.hpp
index 9f82b47..fbe1d6a 100644
--- a/utils.hpp
+++ b/utils.hpp
@@ -44,11 +44,17 @@
     /** @struct Make
      *  @brief Return variant visitor.
      *
-     *  struct Make specialization if Arg is in T (int -> variant<int, char>).
+     *  struct Make specialization if Arg is in T (int -> variant<int, char>),
+     *  but not a string. Strings are used to represent enumerations by
+     *  sdbusplus, so they are attempted in the following specialization.
      */
     template <typename T, typename Arg>
-    struct Make<T, Arg,
-                typename std::enable_if_t<std::is_convertible_v<Arg, T>>>
+    struct Make<
+        T, Arg,
+        typename std::enable_if_t<
+            !std::is_same_v<std::string,
+                            std::remove_cv_t<std::remove_reference_t<Arg>>> &&
+            std::is_convertible_v<Arg, T>>>
     {
         static auto make(Arg&& arg)
         {
@@ -59,16 +65,16 @@
     /** @struct Make
      *  @brief Return variant visitor.
      *
-     *  struct Make specialization if Arg is a string, but not otherwise
-     *  directly convertable by C++ conversion constructors.  Strings might
-     *  be convertable using underlying sdbusplus routines, so give them an
-     *  attempt.
+     *  struct Make specialization if Arg is a string.Strings might
+     *  be convertable (for ex. to enumerations) using underlying sdbusplus
+     *  routines, so give them an attempt. In case the string is not convertible
+     *  to an enumeration, sdbusplus::message::convert_from_string will return a
+     *  string back anyway.
      */
     template <typename T, typename Arg>
     struct Make<
         T, Arg,
         typename std::enable_if_t<
-            !std::is_convertible_v<Arg, T> &&
             std::is_same_v<std::string,
                            std::remove_cv_t<std::remove_reference_t<Arg>>> &&
             sdbusplus::message::has_convert_from_string_v<T>>>