blob: 96a2422000e3f62970ff68c30b73ab07fd1c374d [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{
50 static std::any op(sdbusplus::bus::bus& bus, const char* path,
51 const Interface&)
52 {
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{
60 static std::any op(sdbusplus::bus::bus& bus, const char* path,
61 const Interface& props)
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));
74 }
75};
76
77template <typename T, typename Enable = void>
78struct AssignInterface
79{
80 static void op(const Interface&, std::any&)
Brad Bishopa83db302020-12-06 14:51:23 -050081 {}
Brad Bishop9cc42ab2018-12-12 16:36:51 -050082};
83
84template <typename T>
85struct AssignInterface<T, std::enable_if_t<HasProperties<T>::value>>
86{
87 static void op(const Interface& props, std::any& holder)
88 {
89 auto& iface = *std::any_cast<std::shared_ptr<T>&>(holder);
90 for (const auto& p : props)
91 {
92 iface.setPropertyByName(
93 p.first,
94 convertVariant<typename T::PropertiesVariant>(p.second));
95 }
96 }
97};
98
99template <typename T, typename Ops, typename Enable = void>
100struct SerializeInterface
101{
102 static void op(const std::string& path, const std::string& iface,
103 const std::any&)
104 {
105 Ops::serialize(path, iface);
106 }
107};
108
109template <typename T, typename Ops>
110struct SerializeInterface<T, Ops, std::enable_if_t<HasProperties<T>::value>>
111{
112 static void op(const std::string& path, const std::string& iface,
113 const std::any& holder)
114 {
115 const auto& object = *std::any_cast<const std::shared_ptr<T>&>(holder);
116 Ops::serialize(path, iface, object);
117 }
118};
119
120template <typename T, typename Ops, typename Enable = void>
121struct DeserializeInterface
122{
123 static void op(const std::string& path, const std::string& iface, std::any&)
124 {
125 Ops::deserialize(path, iface);
126 }
127};
128
129template <typename T, typename Ops>
130struct DeserializeInterface<T, Ops, std::enable_if_t<HasProperties<T>::value>>
131{
132 static void op(const std::string& path, const std::string& iface,
133 std::any& holder)
134 {
135 auto& object = *std::any_cast<std::shared_ptr<T>&>(holder);
136 Ops::deserialize(path, iface, object);
137 }
138};
139
140struct DummyInterface
Brad Bishopa83db302020-12-06 14:51:23 -0500141{};
Brad Bishop9cc42ab2018-12-12 16:36:51 -0500142using MakeInterfaceType =
143 std::add_pointer_t<decltype(MakeInterface<DummyInterface>::op)>;
144using AssignInterfaceType =
145 std::add_pointer_t<decltype(AssignInterface<DummyInterface>::op)>;
146template <typename Ops>
147using SerializeInterfaceType =
148 std::add_pointer_t<decltype(SerializeInterface<DummyInterface, Ops>::op)>;
149template <typename Ops>
150using DeserializeInterfaceType =
151 std::add_pointer_t<decltype(DeserializeInterface<DummyInterface, Ops>::op)>;
152
153} // namespace manager
154} // namespace inventory
155} // namespace phosphor