| #pragma once |
| |
| #include "types.hpp" |
| #include "utils.hpp" |
| |
| #include <any> |
| #include <map> |
| #include <memory> |
| #include <string> |
| #include <type_traits> |
| #include <utility> |
| |
| namespace sdbusplus |
| { |
| namespace bus |
| { |
| class bus; |
| } |
| } // namespace sdbusplus |
| |
| namespace phosphor |
| { |
| namespace inventory |
| { |
| namespace manager |
| { |
| |
| template <typename T> |
| struct HasProperties |
| { |
| private: |
| using yes = char; |
| struct no |
| { |
| char array[2]; |
| }; |
| |
| template <typename U> |
| static constexpr yes test(typename U::PropertiesVariant*); |
| template <typename U> |
| static constexpr no test(...); |
| |
| public: |
| static constexpr auto value = sizeof(test<T>(0)) == sizeof(yes); |
| }; |
| |
| template <typename T, typename Enable = void> |
| struct MakeInterface |
| { |
| static std::any op(sdbusplus::bus_t& bus, const char* path, |
| const Interface&, bool) |
| { |
| return std::any(std::make_shared<T>(bus, path)); |
| } |
| }; |
| |
| template <typename T> |
| struct MakeInterface<T, std::enable_if_t<HasProperties<T>::value>> |
| { |
| static std::any op(sdbusplus::bus_t& bus, const char* path, |
| const Interface& props, bool deferSignal) |
| { |
| using InterfaceVariant = |
| std::map<std::string, typename T::PropertiesVariant>; |
| |
| InterfaceVariant v; |
| for (const auto& p : props) |
| { |
| v.emplace(p.first, |
| convertVariant<typename T::PropertiesVariant>(p.second)); |
| } |
| |
| return std::any(std::make_shared<T>(bus, path, v, deferSignal)); |
| } |
| }; |
| |
| template <typename T, typename Enable = void> |
| struct GetPropertyValue |
| { |
| static InterfaceVariantType op(const std::string /* propertyName */, |
| std::any& /* holder */) |
| { |
| return InterfaceVariantType{}; |
| } |
| }; |
| |
| template <typename T> |
| struct GetPropertyValue<T, std::enable_if_t<HasProperties<T>::value>> |
| { |
| static InterfaceVariantType op(const std::string propertyName, |
| std::any& holder) |
| { |
| auto& iface = *std::any_cast<std::shared_ptr<T>&>(holder); |
| auto property = iface.getPropertyByName(propertyName); |
| return convertVariant<InterfaceVariantType>(property); |
| } |
| }; |
| |
| template <typename T, typename Enable = void> |
| struct AssignInterface |
| { |
| static void op(const Interface&, std::any&, bool) {} |
| }; |
| |
| template <typename T> |
| struct AssignInterface<T, std::enable_if_t<HasProperties<T>::value>> |
| { |
| static void op(const Interface& props, std::any& holder, bool deferSignal) |
| { |
| auto& iface = *std::any_cast<std::shared_ptr<T>&>(holder); |
| for (const auto& p : props) |
| { |
| iface.setPropertyByName( |
| p.first, |
| convertVariant<typename T::PropertiesVariant>(p.second), |
| deferSignal); |
| } |
| } |
| }; |
| |
| template <typename T, typename Ops, typename Enable = void> |
| struct SerializeInterface |
| { |
| static void op(const std::string& path, const std::string& iface, |
| const std::any&) |
| { |
| Ops::serialize(path, iface); |
| } |
| }; |
| |
| template <typename T, typename Ops> |
| struct SerializeInterface<T, Ops, std::enable_if_t<HasProperties<T>::value>> |
| { |
| static void op(const std::string& path, const std::string& iface, |
| const std::any& holder) |
| { |
| const auto& object = *std::any_cast<const std::shared_ptr<T>&>(holder); |
| Ops::serialize(path, iface, object); |
| } |
| }; |
| |
| template <typename T, typename Ops, typename Enable = void> |
| struct DeserializeInterface |
| { |
| static void op(const std::string& path, const std::string& iface, std::any&) |
| { |
| Ops::deserialize(path, iface); |
| } |
| }; |
| |
| template <typename T, typename Ops> |
| struct DeserializeInterface<T, Ops, std::enable_if_t<HasProperties<T>::value>> |
| { |
| static void op(const std::string& path, const std::string& iface, |
| std::any& holder) |
| { |
| auto& object = *std::any_cast<std::shared_ptr<T>&>(holder); |
| Ops::deserialize(path, iface, object); |
| } |
| }; |
| |
| struct DummyInterface |
| {}; |
| using MakeInterfaceType = |
| std::add_pointer_t<decltype(MakeInterface<DummyInterface>::op)>; |
| using AssignInterfaceType = |
| std::add_pointer_t<decltype(AssignInterface<DummyInterface>::op)>; |
| template <typename Ops> |
| using SerializeInterfaceType = |
| std::add_pointer_t<decltype(SerializeInterface<DummyInterface, Ops>::op)>; |
| template <typename Ops> |
| using DeserializeInterfaceType = |
| std::add_pointer_t<decltype(DeserializeInterface<DummyInterface, Ops>::op)>; |
| using GetPropertyValueType = |
| std::add_pointer_t<decltype(GetPropertyValue<DummyInterface>::op)>; |
| |
| } // namespace manager |
| } // namespace inventory |
| } // namespace phosphor |