1 #pragma once 2 3 #include "types.hpp" 4 #include "utils.hpp" 5 6 #include <any> 7 #include <map> 8 #include <memory> 9 #include <string> 10 #include <type_traits> 11 #include <utility> 12 13 namespace sdbusplus 14 { 15 namespace bus 16 { 17 class bus; 18 } 19 } // namespace sdbusplus 20 21 namespace phosphor 22 { 23 namespace inventory 24 { 25 namespace manager 26 { 27 28 template <typename T> 29 struct HasProperties 30 { 31 private: 32 using yes = char; 33 struct no 34 { 35 char array[2]; 36 }; 37 38 template <typename U> 39 static constexpr yes test(typename U::PropertiesVariant*); 40 template <typename U> 41 static constexpr no test(...); 42 43 public: 44 static constexpr auto value = sizeof(test<T>(0)) == sizeof(yes); 45 }; 46 47 template <typename T, typename Enable = void> 48 struct MakeInterface 49 { 50 static std::any op(sdbusplus::bus::bus& bus, const char* path, 51 const Interface&, bool) 52 { 53 return std::any(std::make_shared<T>(bus, path)); 54 } 55 }; 56 57 template <typename T> 58 struct MakeInterface<T, std::enable_if_t<HasProperties<T>::value>> 59 { 60 static std::any op(sdbusplus::bus::bus& bus, const char* path, 61 const Interface& props, bool deferSignal) 62 { 63 using InterfaceVariant = 64 std::map<std::string, typename T::PropertiesVariant>; 65 66 InterfaceVariant v; 67 for (const auto& p : props) 68 { 69 v.emplace(p.first, 70 convertVariant<typename T::PropertiesVariant>(p.second)); 71 } 72 73 return std::any(std::make_shared<T>(bus, path, v, deferSignal)); 74 } 75 }; 76 77 template <typename T, typename Enable = void> 78 struct GetPropertyValue 79 { 80 static InterfaceVariantType op(const std::string /* propertyName */, 81 std::any& /* holder */) 82 { 83 return InterfaceVariantType{}; 84 } 85 }; 86 87 template <typename T> 88 struct GetPropertyValue<T, std::enable_if_t<HasProperties<T>::value>> 89 { 90 static InterfaceVariantType op(const std::string propertyName, 91 std::any& holder) 92 { 93 auto& iface = *std::any_cast<std::shared_ptr<T>&>(holder); 94 auto property = iface.getPropertyByName(propertyName); 95 return convertVariant<InterfaceVariantType>(property); 96 } 97 }; 98 99 template <typename T, typename Enable = void> 100 struct AssignInterface 101 { 102 static void op(const Interface&, std::any&, bool) 103 {} 104 }; 105 106 template <typename T> 107 struct AssignInterface<T, std::enable_if_t<HasProperties<T>::value>> 108 { 109 static void op(const Interface& props, std::any& holder, bool deferSignal) 110 { 111 auto& iface = *std::any_cast<std::shared_ptr<T>&>(holder); 112 for (const auto& p : props) 113 { 114 iface.setPropertyByName( 115 p.first, 116 convertVariant<typename T::PropertiesVariant>(p.second), 117 deferSignal); 118 } 119 } 120 }; 121 122 template <typename T, typename Ops, typename Enable = void> 123 struct SerializeInterface 124 { 125 static void op(const std::string& path, const std::string& iface, 126 const std::any&) 127 { 128 Ops::serialize(path, iface); 129 } 130 }; 131 132 template <typename T, typename Ops> 133 struct SerializeInterface<T, Ops, std::enable_if_t<HasProperties<T>::value>> 134 { 135 static void op(const std::string& path, const std::string& iface, 136 const std::any& holder) 137 { 138 const auto& object = *std::any_cast<const std::shared_ptr<T>&>(holder); 139 Ops::serialize(path, iface, object); 140 } 141 }; 142 143 template <typename T, typename Ops, typename Enable = void> 144 struct DeserializeInterface 145 { 146 static void op(const std::string& path, const std::string& iface, std::any&) 147 { 148 Ops::deserialize(path, iface); 149 } 150 }; 151 152 template <typename T, typename Ops> 153 struct DeserializeInterface<T, Ops, std::enable_if_t<HasProperties<T>::value>> 154 { 155 static void op(const std::string& path, const std::string& iface, 156 std::any& holder) 157 { 158 auto& object = *std::any_cast<std::shared_ptr<T>&>(holder); 159 Ops::deserialize(path, iface, object); 160 } 161 }; 162 163 struct DummyInterface 164 {}; 165 using MakeInterfaceType = 166 std::add_pointer_t<decltype(MakeInterface<DummyInterface>::op)>; 167 using AssignInterfaceType = 168 std::add_pointer_t<decltype(AssignInterface<DummyInterface>::op)>; 169 template <typename Ops> 170 using SerializeInterfaceType = 171 std::add_pointer_t<decltype(SerializeInterface<DummyInterface, Ops>::op)>; 172 template <typename Ops> 173 using DeserializeInterfaceType = 174 std::add_pointer_t<decltype(DeserializeInterface<DummyInterface, Ops>::op)>; 175 using GetPropertyValueType = 176 std::add_pointer_t<decltype(GetPropertyValue<DummyInterface>::op)>; 177 178 } // namespace manager 179 } // namespace inventory 180 } // namespace phosphor 181