| #pragma once |
| |
| #include <nlohmann/json.hpp> |
| #include <sdbusplus/message/types.hpp> |
| |
| namespace utils |
| { |
| |
| inline void from_json(const nlohmann::json& j, |
| sdbusplus::message::object_path& o) |
| { |
| o = j.get<std::string>(); |
| } |
| |
| inline void from_json(const nlohmann::json& j, |
| std::vector<sdbusplus::message::object_path>& o) |
| { |
| o.clear(); |
| for (const nlohmann::json& item : j) |
| { |
| o.emplace_back(item.get<std::string>()); |
| } |
| } |
| |
| namespace detail |
| { |
| |
| template <class T> |
| struct has_utils_from_json |
| { |
| template <class U> |
| static U& ref(); |
| |
| template <class U> |
| static std::true_type check( |
| decltype(utils::from_json(ref<const nlohmann::json>(), ref<U>()))*); |
| |
| template <class> |
| static std::false_type check(...); |
| |
| static constexpr bool value = |
| decltype(check<std::decay_t<T>>(nullptr))::value; |
| }; |
| |
| template <class T> |
| constexpr bool has_utils_from_json_v = has_utils_from_json<T>::value; |
| |
| } // namespace detail |
| |
| template <class, class...> |
| struct LabeledTuple; |
| |
| template <class... Args, class... Labels> |
| struct LabeledTuple<std::tuple<Args...>, Labels...> |
| { |
| LabeledTuple() = delete; |
| |
| static_assert(sizeof...(Args) == sizeof...(Labels)); |
| |
| static nlohmann::json to_json(const std::tuple<Args...>& tuple) |
| { |
| nlohmann::json j; |
| to_json_all(j, tuple, std::make_index_sequence<sizeof...(Args)>()); |
| return j; |
| } |
| |
| static std::tuple<Args...> from_json(const nlohmann::json& j) |
| { |
| std::tuple<Args...> value; |
| from_json_all(j, value, std::make_index_sequence<sizeof...(Args)>()); |
| return value; |
| } |
| |
| private: |
| template <size_t... Idx> |
| static void to_json_all(nlohmann::json& j, const std::tuple<Args...>& tuple, |
| std::index_sequence<Idx...>) |
| { |
| (to_json_item<Idx>(j, tuple), ...); |
| } |
| |
| template <size_t Idx> |
| static void to_json_item(nlohmann::json& j, |
| const std::tuple<Args...>& tuple) |
| { |
| using Label = std::tuple_element_t<Idx, std::tuple<Labels...>>; |
| j[Label::str()] = std::get<Idx>(tuple); |
| } |
| |
| template <size_t... Idx> |
| static void from_json_all(const nlohmann::json& j, |
| std::tuple<Args...>& value, |
| std::index_sequence<Idx...>) |
| { |
| (from_json_item<Idx>(j, value), ...); |
| } |
| |
| template <size_t Idx> |
| static void from_json_item(const nlohmann::json& j, |
| std::tuple<Args...>& value) |
| { |
| using Label = std::tuple_element_t<Idx, std::tuple<Labels...>>; |
| using T = std::tuple_element_t<Idx, std::tuple<Args...>>; |
| const nlohmann::json& item = j.at(Label::str()); |
| if constexpr (detail::has_utils_from_json_v<T>) |
| { |
| T& v = std::get<Idx>(value); |
| utils::from_json(item, v); |
| } |
| else |
| { |
| std::get<Idx>(value) = item.get<T>(); |
| } |
| } |
| }; |
| |
| } // namespace utils |