// SPDX-License-Identifier: Apache-2.0 // Copyright Pionix GmbH and Contributors to EVerest #ifndef UTILS_CONVERSIONS_HPP #define UTILS_CONVERSIONS_HPP #include #include #include namespace Everest { using json = nlohmann::json; namespace detail { template constexpr bool is_type_compatible(nlohmann::json::value_t json_type); template <> constexpr inline bool is_type_compatible(nlohmann::json::value_t json_type) { return json_type == nlohmann::json::value_t::null; } template <> constexpr inline bool is_type_compatible(nlohmann::json::value_t json_type) { return json_type == nlohmann::json::value_t::boolean; } template <> constexpr inline bool is_type_compatible(nlohmann::json::value_t json_type) { return json_type == nlohmann::json::value_t::number_integer || json_type == nlohmann::json::value_t::number_unsigned; } template <> constexpr inline bool is_type_compatible(nlohmann::json::value_t json_type) { return json_type == nlohmann::json::value_t::number_float; } template <> constexpr inline bool is_type_compatible(nlohmann::json::value_t json_type) { return json_type == nlohmann::json::value_t::string; } template <> constexpr inline bool is_type_compatible(nlohmann::json::value_t json_type) { return json_type == nlohmann::json::value_t::array; } template <> constexpr inline bool is_type_compatible(nlohmann::json::value_t json_type) { return json_type == nlohmann::json::value_t::object; } template bool json_to_variant_impl(T& /*to*/, const nlohmann::json& /*from*/) noexcept { return false; } template bool json_to_variant_impl(VariantType& to, const nlohmann::json& from) noexcept { if (is_type_compatible(from.type())) { to = from.get(); return true; } return json_to_variant_impl(to, from); } } // namespace detail template static std::variant json_to_variant(const nlohmann::json& j) { std::variant var; if (detail::json_to_variant_impl, Ts...>(var, j)) { return var; } throw std::runtime_error("The given json object doesn't contain any type, the std::variant is aware of"); } template nlohmann::json variant_to_json(T variant) { return std::visit( [](auto&& arg) -> nlohmann::json { using U = std::decay_t; if constexpr (std::is_same_v) { // FIXME: do we really want this? return nlohmann::json(nullptr); } else { return arg; } }, variant); } namespace conversions { /// The json tag for the error type. constexpr auto ERROR_TYPE = "__everest__error_type"; /// The json tag for the error message. constexpr auto ERROR_MSG = "__everest__error_msg"; std::string cmd_error_type_to_string(CmdErrorType cmd_error_type); CmdErrorType string_to_cmd_error_type(const std::string& cmd_error_string); } // namespace conversions void to_json(nlohmann::json& j, const CmdResultError& e); void from_json(const nlohmann::json& j, CmdResultError& e); } // namespace Everest #endif // UTILS_CONVERSIONS_HPP