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