1*e2362796SWludzik, Jozef #pragma once 2*e2362796SWludzik, Jozef 3*e2362796SWludzik, Jozef #include <nlohmann/json.hpp> 4*e2362796SWludzik, Jozef #include <sdbusplus/message/types.hpp> 5*e2362796SWludzik, Jozef 6*e2362796SWludzik, Jozef namespace utils 7*e2362796SWludzik, Jozef { 8*e2362796SWludzik, Jozef 9*e2362796SWludzik, Jozef inline void from_json(const nlohmann::json& j, 10*e2362796SWludzik, Jozef sdbusplus::message::object_path& o) 11*e2362796SWludzik, Jozef { 12*e2362796SWludzik, Jozef o = j.get<std::string>(); 13*e2362796SWludzik, Jozef } 14*e2362796SWludzik, Jozef 15*e2362796SWludzik, Jozef inline void from_json(const nlohmann::json& j, 16*e2362796SWludzik, Jozef std::vector<sdbusplus::message::object_path>& o) 17*e2362796SWludzik, Jozef { 18*e2362796SWludzik, Jozef o.clear(); 19*e2362796SWludzik, Jozef for (const nlohmann::json& item : j) 20*e2362796SWludzik, Jozef { 21*e2362796SWludzik, Jozef o.emplace_back(item.get<std::string>()); 22*e2362796SWludzik, Jozef } 23*e2362796SWludzik, Jozef } 24*e2362796SWludzik, Jozef 25*e2362796SWludzik, Jozef namespace detail 26*e2362796SWludzik, Jozef { 27*e2362796SWludzik, Jozef 28*e2362796SWludzik, Jozef template <class T> 29*e2362796SWludzik, Jozef struct has_utils_from_json 30*e2362796SWludzik, Jozef { 31*e2362796SWludzik, Jozef template <class U> 32*e2362796SWludzik, Jozef static U& ref(); 33*e2362796SWludzik, Jozef 34*e2362796SWludzik, Jozef template <class U> 35*e2362796SWludzik, Jozef static std::true_type check( 36*e2362796SWludzik, Jozef decltype(utils::from_json(ref<const nlohmann::json>(), ref<U>()))*); 37*e2362796SWludzik, Jozef 38*e2362796SWludzik, Jozef template <class> 39*e2362796SWludzik, Jozef static std::false_type check(...); 40*e2362796SWludzik, Jozef 41*e2362796SWludzik, Jozef static constexpr bool value = 42*e2362796SWludzik, Jozef decltype(check<std::decay_t<T>>(nullptr))::value; 43*e2362796SWludzik, Jozef }; 44*e2362796SWludzik, Jozef 45*e2362796SWludzik, Jozef template <class T> 46*e2362796SWludzik, Jozef constexpr bool has_utils_from_json_v = has_utils_from_json<T>::value; 47*e2362796SWludzik, Jozef 48*e2362796SWludzik, Jozef } // namespace detail 49*e2362796SWludzik, Jozef 50*e2362796SWludzik, Jozef template <class, class...> 51*e2362796SWludzik, Jozef struct LabeledTuple; 52*e2362796SWludzik, Jozef 53*e2362796SWludzik, Jozef template <class... Args, class... Labels> 54*e2362796SWludzik, Jozef struct LabeledTuple<std::tuple<Args...>, Labels...> 55*e2362796SWludzik, Jozef { 56*e2362796SWludzik, Jozef LabeledTuple() = delete; 57*e2362796SWludzik, Jozef 58*e2362796SWludzik, Jozef static_assert(sizeof...(Args) == sizeof...(Labels)); 59*e2362796SWludzik, Jozef 60*e2362796SWludzik, Jozef static nlohmann::json to_json(const std::tuple<Args...>& tuple) 61*e2362796SWludzik, Jozef { 62*e2362796SWludzik, Jozef nlohmann::json j; 63*e2362796SWludzik, Jozef to_json_all(j, tuple, std::make_index_sequence<sizeof...(Args)>()); 64*e2362796SWludzik, Jozef return j; 65*e2362796SWludzik, Jozef } 66*e2362796SWludzik, Jozef 67*e2362796SWludzik, Jozef static std::tuple<Args...> from_json(const nlohmann::json& j) 68*e2362796SWludzik, Jozef { 69*e2362796SWludzik, Jozef std::tuple<Args...> value; 70*e2362796SWludzik, Jozef from_json_all(j, value, std::make_index_sequence<sizeof...(Args)>()); 71*e2362796SWludzik, Jozef return value; 72*e2362796SWludzik, Jozef } 73*e2362796SWludzik, Jozef 74*e2362796SWludzik, Jozef private: 75*e2362796SWludzik, Jozef template <size_t... Idx> 76*e2362796SWludzik, Jozef static void to_json_all(nlohmann::json& j, const std::tuple<Args...>& tuple, 77*e2362796SWludzik, Jozef std::index_sequence<Idx...>) 78*e2362796SWludzik, Jozef { 79*e2362796SWludzik, Jozef (to_json_item<Idx>(j, tuple), ...); 80*e2362796SWludzik, Jozef } 81*e2362796SWludzik, Jozef 82*e2362796SWludzik, Jozef template <size_t Idx> 83*e2362796SWludzik, Jozef static void to_json_item(nlohmann::json& j, 84*e2362796SWludzik, Jozef const std::tuple<Args...>& tuple) 85*e2362796SWludzik, Jozef { 86*e2362796SWludzik, Jozef using Label = std::tuple_element_t<Idx, std::tuple<Labels...>>; 87*e2362796SWludzik, Jozef j[Label::str()] = std::get<Idx>(tuple); 88*e2362796SWludzik, Jozef } 89*e2362796SWludzik, Jozef 90*e2362796SWludzik, Jozef template <size_t... Idx> 91*e2362796SWludzik, Jozef static void from_json_all(const nlohmann::json& j, 92*e2362796SWludzik, Jozef std::tuple<Args...>& value, 93*e2362796SWludzik, Jozef std::index_sequence<Idx...>) 94*e2362796SWludzik, Jozef { 95*e2362796SWludzik, Jozef (from_json_item<Idx>(j, value), ...); 96*e2362796SWludzik, Jozef } 97*e2362796SWludzik, Jozef 98*e2362796SWludzik, Jozef template <size_t Idx> 99*e2362796SWludzik, Jozef static void from_json_item(const nlohmann::json& j, 100*e2362796SWludzik, Jozef std::tuple<Args...>& value) 101*e2362796SWludzik, Jozef { 102*e2362796SWludzik, Jozef using Label = std::tuple_element_t<Idx, std::tuple<Labels...>>; 103*e2362796SWludzik, Jozef using T = std::tuple_element_t<Idx, std::tuple<Args...>>; 104*e2362796SWludzik, Jozef const nlohmann::json& item = j.at(Label::str()); 105*e2362796SWludzik, Jozef if constexpr (detail::has_utils_from_json_v<T>) 106*e2362796SWludzik, Jozef { 107*e2362796SWludzik, Jozef T& v = std::get<Idx>(value); 108*e2362796SWludzik, Jozef utils::from_json(item, v); 109*e2362796SWludzik, Jozef } 110*e2362796SWludzik, Jozef else 111*e2362796SWludzik, Jozef { 112*e2362796SWludzik, Jozef std::get<Idx>(value) = item.get<T>(); 113*e2362796SWludzik, Jozef } 114*e2362796SWludzik, Jozef } 115*e2362796SWludzik, Jozef }; 116*e2362796SWludzik, Jozef 117*e2362796SWludzik, Jozef } // namespace utils 118