Add setProperty action

The setProperty action sets a property to a predefined
value when a match occurs.

Change-Id: Ibd3cbb0da86a99e823b9cc00cc0240772d895f7f
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/actions.hpp b/actions.hpp
index 0966ee4..bac934f 100644
--- a/actions.hpp
+++ b/actions.hpp
@@ -47,6 +47,43 @@
 {
     return [path](auto &m){m.destroyObject(path);};
 }
+
+/** @brief Set a property action.
+ *
+ *  Invoke the requested method with a reference to the requested
+ *  sdbusplus server binding interface as a parameter.
+ *
+ *  @tparam T - The sdbusplus server binding interface type.
+ *  @tparam U - The type of the sdbusplus server binding member
+ *      function that sets the property.
+ *  @tparam V - The property value type.
+ *
+ *  @param[in] path - The DBus path on which the property should
+ *      be set.
+ *  @param[in] iface - The DBus interface hosting the property.
+ *  @param[in] member - Pointer to sdbusplus server binding member.
+ *  @param[in] value - The value the property should be set to.
+ *
+ *  @returns - A function object that sets the requested property
+ *      to the requested value.
+ */
+template <typename T, typename U, typename V>
+decltype(auto) setProperty(
+        const char *path, const char *iface,
+        U &&member, V &&value)
+{
+    // The manager is the only parameter passed to actions.
+    // Bind the path, interface, interface member function pointer,
+    // and value to a lambda.  When it is called, forward the
+    // path, interface and value on to the manager member function.
+    return [path, iface, member,
+        value = std::forward<V>(value)](auto &m)
+    {
+        m.template invokeMethod<T>(
+            path, iface, member, value);
+    };
+}
+
 } // namespace actions
 } // namespace manager
 } // namespace inventory
diff --git a/manager.hpp b/manager.hpp
index 6326336..0954953 100644
--- a/manager.hpp
+++ b/manager.hpp
@@ -99,6 +99,33 @@
     /** @brief Drop an object from DBus. */
     void destroyObject(const char *);
 
+    /** @brief Invoke an sdbusplus server binding method.
+     *
+     *  Invoke the requested method with a reference to the requested
+     *  sdbusplus server binding interface as a parameter.
+     *
+     *  @tparam T - The sdbusplus server binding interface type.
+     *  @tparam U - The type of the sdbusplus server binding member.
+     *  @tparam Args - Argument types of the binding member.
+     *
+     *  @param[in] path - The DBus path on which the method should
+     *      be invoked.
+     *  @param[in] interface - The DBus interface hosting the method.
+     *  @param[in] member - Pointer to sdbusplus server binding member.
+     *  @param[in] args - Arguments to forward to the binding member.
+     *
+     *  @returns - The return/value type of the binding method being
+     *      called.
+     */
+    template<typename T, typename U, typename ...Args>
+    decltype(auto) invokeMethod(const char *path, const char *interface,
+            U&& member, Args&&...args)
+    {
+        auto &holder = getInterface<std::unique_ptr<T>>(path, interface);
+        auto &iface = *holder.get();
+        return (iface.*member)(std::forward<Args>(args)...);
+    }
+
     using SigArgs = std::vector<
         std::unique_ptr<
             std::tuple<