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