xref: /openbmc/phosphor-inventory-manager/interface_ops.hpp (revision 7edafe0610b592dc25b9633d7d60a68f7639d66e)
19cc42abfSBrad Bishop #pragma once
29cc42abfSBrad Bishop 
39cc42abfSBrad Bishop #include "types.hpp"
49cc42abfSBrad Bishop #include "utils.hpp"
59cc42abfSBrad Bishop 
69cc42abfSBrad Bishop #include <any>
79cc42abfSBrad Bishop #include <map>
89cc42abfSBrad Bishop #include <memory>
99cc42abfSBrad Bishop #include <string>
109cc42abfSBrad Bishop #include <type_traits>
119cc42abfSBrad Bishop #include <utility>
129cc42abfSBrad Bishop 
139cc42abfSBrad Bishop namespace sdbusplus
149cc42abfSBrad Bishop {
159cc42abfSBrad Bishop namespace bus
169cc42abfSBrad Bishop {
179cc42abfSBrad Bishop class bus;
189cc42abfSBrad Bishop }
199cc42abfSBrad Bishop } // namespace sdbusplus
209cc42abfSBrad Bishop 
219cc42abfSBrad Bishop namespace phosphor
229cc42abfSBrad Bishop {
239cc42abfSBrad Bishop namespace inventory
249cc42abfSBrad Bishop {
259cc42abfSBrad Bishop namespace manager
269cc42abfSBrad Bishop {
279cc42abfSBrad Bishop 
289cc42abfSBrad Bishop template <typename T>
299cc42abfSBrad Bishop struct HasProperties
309cc42abfSBrad Bishop {
319cc42abfSBrad Bishop   private:
329cc42abfSBrad Bishop     using yes = char;
339cc42abfSBrad Bishop     struct no
349cc42abfSBrad Bishop     {
359cc42abfSBrad Bishop         char array[2];
369cc42abfSBrad Bishop     };
379cc42abfSBrad Bishop 
389cc42abfSBrad Bishop     template <typename U>
399cc42abfSBrad Bishop     static constexpr yes test(typename U::PropertiesVariant*);
409cc42abfSBrad Bishop     template <typename U>
419cc42abfSBrad Bishop     static constexpr no test(...);
429cc42abfSBrad Bishop 
439cc42abfSBrad Bishop   public:
449cc42abfSBrad Bishop     static constexpr auto value = sizeof(test<T>(0)) == sizeof(yes);
459cc42abfSBrad Bishop };
469cc42abfSBrad Bishop 
479cc42abfSBrad Bishop template <typename T, typename Enable = void>
489cc42abfSBrad Bishop struct MakeInterface
499cc42abfSBrad Bishop {
opphosphor::inventory::manager::MakeInterface50563306f6SPatrick Williams     static std::any op(sdbusplus::bus_t& bus, const char* path,
51e96f2aa7SBrad Bishop                        const Interface&, bool)
529cc42abfSBrad Bishop     {
539cc42abfSBrad Bishop         return std::any(std::make_shared<T>(bus, path));
549cc42abfSBrad Bishop     }
559cc42abfSBrad Bishop };
569cc42abfSBrad Bishop 
579cc42abfSBrad Bishop template <typename T>
589cc42abfSBrad Bishop struct MakeInterface<T, std::enable_if_t<HasProperties<T>::value>>
599cc42abfSBrad Bishop {
opphosphor::inventory::manager::MakeInterface60563306f6SPatrick Williams     static std::any op(sdbusplus::bus_t& bus, const char* path,
61e96f2aa7SBrad Bishop                        const Interface& props, bool deferSignal)
629cc42abfSBrad Bishop     {
639cc42abfSBrad Bishop         using InterfaceVariant =
649cc42abfSBrad Bishop             std::map<std::string, typename T::PropertiesVariant>;
659cc42abfSBrad Bishop 
669cc42abfSBrad Bishop         InterfaceVariant v;
679cc42abfSBrad Bishop         for (const auto& p : props)
689cc42abfSBrad Bishop         {
699cc42abfSBrad Bishop             v.emplace(p.first,
709cc42abfSBrad Bishop                       convertVariant<typename T::PropertiesVariant>(p.second));
719cc42abfSBrad Bishop         }
729cc42abfSBrad Bishop 
73e96f2aa7SBrad Bishop         return std::any(std::make_shared<T>(bus, path, v, deferSignal));
749cc42abfSBrad Bishop     }
759cc42abfSBrad Bishop };
769cc42abfSBrad Bishop 
779cc42abfSBrad Bishop template <typename T, typename Enable = void>
7859521e87SMatt Spinler struct GetPropertyValue
7959521e87SMatt Spinler {
opphosphor::inventory::manager::GetPropertyValue8023314a5cSGeorge Liu     static InterfaceVariantType op(const std::string /* propertyName */,
8123314a5cSGeorge Liu                                    std::any& /* holder */)
8259521e87SMatt Spinler     {
8359521e87SMatt Spinler         return InterfaceVariantType{};
8459521e87SMatt Spinler     }
8559521e87SMatt Spinler };
8659521e87SMatt Spinler 
8759521e87SMatt Spinler template <typename T>
8859521e87SMatt Spinler struct GetPropertyValue<T, std::enable_if_t<HasProperties<T>::value>>
8959521e87SMatt Spinler {
opphosphor::inventory::manager::GetPropertyValue9059521e87SMatt Spinler     static InterfaceVariantType op(const std::string propertyName,
9159521e87SMatt Spinler                                    std::any& holder)
9259521e87SMatt Spinler     {
9359521e87SMatt Spinler         auto& iface = *std::any_cast<std::shared_ptr<T>&>(holder);
9459521e87SMatt Spinler         auto property = iface.getPropertyByName(propertyName);
9559521e87SMatt Spinler         return convertVariant<InterfaceVariantType>(property);
9659521e87SMatt Spinler     }
9759521e87SMatt Spinler };
9859521e87SMatt Spinler 
9959521e87SMatt Spinler template <typename T, typename Enable = void>
1009cc42abfSBrad Bishop struct AssignInterface
1019cc42abfSBrad Bishop {
opphosphor::inventory::manager::AssignInterface102*7edafe06SPatrick Williams     static void op(const Interface&, std::any&, bool) {}
1039cc42abfSBrad Bishop };
1049cc42abfSBrad Bishop 
1059cc42abfSBrad Bishop template <typename T>
1069cc42abfSBrad Bishop struct AssignInterface<T, std::enable_if_t<HasProperties<T>::value>>
1079cc42abfSBrad Bishop {
opphosphor::inventory::manager::AssignInterface108e96f2aa7SBrad Bishop     static void op(const Interface& props, std::any& holder, bool deferSignal)
1099cc42abfSBrad Bishop     {
1109cc42abfSBrad Bishop         auto& iface = *std::any_cast<std::shared_ptr<T>&>(holder);
1119cc42abfSBrad Bishop         for (const auto& p : props)
1129cc42abfSBrad Bishop         {
1139cc42abfSBrad Bishop             iface.setPropertyByName(
1149cc42abfSBrad Bishop                 p.first,
115e96f2aa7SBrad Bishop                 convertVariant<typename T::PropertiesVariant>(p.second),
116e96f2aa7SBrad Bishop                 deferSignal);
1179cc42abfSBrad Bishop         }
1189cc42abfSBrad Bishop     }
1199cc42abfSBrad Bishop };
1209cc42abfSBrad Bishop 
1219cc42abfSBrad Bishop template <typename T, typename Ops, typename Enable = void>
1229cc42abfSBrad Bishop struct SerializeInterface
1239cc42abfSBrad Bishop {
opphosphor::inventory::manager::SerializeInterface1249cc42abfSBrad Bishop     static void op(const std::string& path, const std::string& iface,
1259cc42abfSBrad Bishop                    const std::any&)
1269cc42abfSBrad Bishop     {
1279cc42abfSBrad Bishop         Ops::serialize(path, iface);
1289cc42abfSBrad Bishop     }
1299cc42abfSBrad Bishop };
1309cc42abfSBrad Bishop 
1319cc42abfSBrad Bishop template <typename T, typename Ops>
1329cc42abfSBrad Bishop struct SerializeInterface<T, Ops, std::enable_if_t<HasProperties<T>::value>>
1339cc42abfSBrad Bishop {
opphosphor::inventory::manager::SerializeInterface1349cc42abfSBrad Bishop     static void op(const std::string& path, const std::string& iface,
1359cc42abfSBrad Bishop                    const std::any& holder)
1369cc42abfSBrad Bishop     {
1379cc42abfSBrad Bishop         const auto& object = *std::any_cast<const std::shared_ptr<T>&>(holder);
1389cc42abfSBrad Bishop         Ops::serialize(path, iface, object);
1399cc42abfSBrad Bishop     }
1409cc42abfSBrad Bishop };
1419cc42abfSBrad Bishop 
1429cc42abfSBrad Bishop template <typename T, typename Ops, typename Enable = void>
1439cc42abfSBrad Bishop struct DeserializeInterface
1449cc42abfSBrad Bishop {
opphosphor::inventory::manager::DeserializeInterface1459cc42abfSBrad Bishop     static void op(const std::string& path, const std::string& iface, std::any&)
1469cc42abfSBrad Bishop     {
1479cc42abfSBrad Bishop         Ops::deserialize(path, iface);
1489cc42abfSBrad Bishop     }
1499cc42abfSBrad Bishop };
1509cc42abfSBrad Bishop 
1519cc42abfSBrad Bishop template <typename T, typename Ops>
1529cc42abfSBrad Bishop struct DeserializeInterface<T, Ops, std::enable_if_t<HasProperties<T>::value>>
1539cc42abfSBrad Bishop {
opphosphor::inventory::manager::DeserializeInterface1549cc42abfSBrad Bishop     static void op(const std::string& path, const std::string& iface,
1559cc42abfSBrad Bishop                    std::any& holder)
1569cc42abfSBrad Bishop     {
1579cc42abfSBrad Bishop         auto& object = *std::any_cast<std::shared_ptr<T>&>(holder);
1589cc42abfSBrad Bishop         Ops::deserialize(path, iface, object);
1599cc42abfSBrad Bishop     }
1609cc42abfSBrad Bishop };
1619cc42abfSBrad Bishop 
1629cc42abfSBrad Bishop struct DummyInterface
163a83db30eSBrad Bishop {};
1649cc42abfSBrad Bishop using MakeInterfaceType =
1659cc42abfSBrad Bishop     std::add_pointer_t<decltype(MakeInterface<DummyInterface>::op)>;
1669cc42abfSBrad Bishop using AssignInterfaceType =
1679cc42abfSBrad Bishop     std::add_pointer_t<decltype(AssignInterface<DummyInterface>::op)>;
1689cc42abfSBrad Bishop template <typename Ops>
1699cc42abfSBrad Bishop using SerializeInterfaceType =
1709cc42abfSBrad Bishop     std::add_pointer_t<decltype(SerializeInterface<DummyInterface, Ops>::op)>;
1719cc42abfSBrad Bishop template <typename Ops>
1729cc42abfSBrad Bishop using DeserializeInterfaceType =
1739cc42abfSBrad Bishop     std::add_pointer_t<decltype(DeserializeInterface<DummyInterface, Ops>::op)>;
17459521e87SMatt Spinler using GetPropertyValueType =
17559521e87SMatt Spinler     std::add_pointer_t<decltype(GetPropertyValue<DummyInterface>::op)>;
1769cc42abfSBrad Bishop 
1779cc42abfSBrad Bishop } // namespace manager
1789cc42abfSBrad Bishop } // namespace inventory
1799cc42abfSBrad Bishop } // namespace phosphor
180