blob: eee0bd247725c721e00dc5288eb4dd5a91f443eb [file] [log] [blame]
Brad Bishop9cc42ab2018-12-12 16:36:51 -05001#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
13namespace sdbusplus
14{
15namespace bus
16{
17class bus;
18}
19} // namespace sdbusplus
20
21namespace phosphor
22{
23namespace inventory
24{
25namespace manager
26{
27
28template <typename T>
29struct 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
47template <typename T, typename Enable = void>
48struct MakeInterface
49{
Patrick Williams563306f2022-07-22 19:26:52 -050050 static std::any op(sdbusplus::bus_t& bus, const char* path,
Brad Bishope96f2aa2020-12-06 19:09:09 -050051 const Interface&, bool)
Brad Bishop9cc42ab2018-12-12 16:36:51 -050052 {
53 return std::any(std::make_shared<T>(bus, path));
54 }
55};
56
57template <typename T>
58struct MakeInterface<T, std::enable_if_t<HasProperties<T>::value>>
59{
Patrick Williams563306f2022-07-22 19:26:52 -050060 static std::any op(sdbusplus::bus_t& bus, const char* path,
Brad Bishope96f2aa2020-12-06 19:09:09 -050061 const Interface& props, bool deferSignal)
Brad Bishop9cc42ab2018-12-12 16:36:51 -050062 {
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
Brad Bishope96f2aa2020-12-06 19:09:09 -050073 return std::any(std::make_shared<T>(bus, path, v, deferSignal));
Brad Bishop9cc42ab2018-12-12 16:36:51 -050074 }
75};
76
77template <typename T, typename Enable = void>
Matt Spinler59521e82021-02-11 13:41:06 -060078struct GetPropertyValue
79{
George Liu23314a52022-04-13 18:26:03 +080080 static InterfaceVariantType op(const std::string /* propertyName */,
81 std::any& /* holder */)
Matt Spinler59521e82021-02-11 13:41:06 -060082 {
83 return InterfaceVariantType{};
84 }
85};
86
87template <typename T>
88struct 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
99template <typename T, typename Enable = void>
Brad Bishop9cc42ab2018-12-12 16:36:51 -0500100struct AssignInterface
101{
Patrick Williams7edafe02023-05-10 07:50:28 -0500102 static void op(const Interface&, std::any&, bool) {}
Brad Bishop9cc42ab2018-12-12 16:36:51 -0500103};
104
105template <typename T>
106struct AssignInterface<T, std::enable_if_t<HasProperties<T>::value>>
107{
Brad Bishope96f2aa2020-12-06 19:09:09 -0500108 static void op(const Interface& props, std::any& holder, bool deferSignal)
Brad Bishop9cc42ab2018-12-12 16:36:51 -0500109 {
110 auto& iface = *std::any_cast<std::shared_ptr<T>&>(holder);
111 for (const auto& p : props)
112 {
113 iface.setPropertyByName(
114 p.first,
Brad Bishope96f2aa2020-12-06 19:09:09 -0500115 convertVariant<typename T::PropertiesVariant>(p.second),
116 deferSignal);
Brad Bishop9cc42ab2018-12-12 16:36:51 -0500117 }
118 }
119};
120
121template <typename T, typename Ops, typename Enable = void>
122struct SerializeInterface
123{
124 static void op(const std::string& path, const std::string& iface,
125 const std::any&)
126 {
127 Ops::serialize(path, iface);
128 }
129};
130
131template <typename T, typename Ops>
132struct SerializeInterface<T, Ops, std::enable_if_t<HasProperties<T>::value>>
133{
134 static void op(const std::string& path, const std::string& iface,
135 const std::any& holder)
136 {
137 const auto& object = *std::any_cast<const std::shared_ptr<T>&>(holder);
138 Ops::serialize(path, iface, object);
139 }
140};
141
142template <typename T, typename Ops, typename Enable = void>
143struct DeserializeInterface
144{
145 static void op(const std::string& path, const std::string& iface, std::any&)
146 {
147 Ops::deserialize(path, iface);
148 }
149};
150
151template <typename T, typename Ops>
152struct DeserializeInterface<T, Ops, std::enable_if_t<HasProperties<T>::value>>
153{
154 static void op(const std::string& path, const std::string& iface,
155 std::any& holder)
156 {
157 auto& object = *std::any_cast<std::shared_ptr<T>&>(holder);
158 Ops::deserialize(path, iface, object);
159 }
160};
161
162struct DummyInterface
Brad Bishopa83db302020-12-06 14:51:23 -0500163{};
Brad Bishop9cc42ab2018-12-12 16:36:51 -0500164using MakeInterfaceType =
165 std::add_pointer_t<decltype(MakeInterface<DummyInterface>::op)>;
166using AssignInterfaceType =
167 std::add_pointer_t<decltype(AssignInterface<DummyInterface>::op)>;
168template <typename Ops>
169using SerializeInterfaceType =
170 std::add_pointer_t<decltype(SerializeInterface<DummyInterface, Ops>::op)>;
171template <typename Ops>
172using DeserializeInterfaceType =
173 std::add_pointer_t<decltype(DeserializeInterface<DummyInterface, Ops>::op)>;
Matt Spinler59521e82021-02-11 13:41:06 -0600174using GetPropertyValueType =
175 std::add_pointer_t<decltype(GetPropertyValue<DummyInterface>::op)>;
Brad Bishop9cc42ab2018-12-12 16:36:51 -0500176
177} // namespace manager
178} // namespace inventory
179} // namespace phosphor