From 049a4752465f4f7a079d3a9fa02c9345ad443f4b Mon Sep 17 00:00:00 2001 From: IESE-T3 <47669401+IESE-T3@users.noreply.github.com> Date: Wed, 17 Jul 2024 15:42:24 +0200 Subject: [PATCH] Refactors of json util functions (#3) --- include/DRAMUtils/memspec/MemSpec.h | 4 +- include/DRAMUtils/util/id_variant.h | 127 +++++++++++++++++++++++++++- include/DRAMUtils/util/json.h | 105 +---------------------- 3 files changed, 128 insertions(+), 108 deletions(-) diff --git a/include/DRAMUtils/memspec/MemSpec.h b/include/DRAMUtils/memspec/MemSpec.h index c452bb4..8aa99a5 100644 --- a/include/DRAMUtils/memspec/MemSpec.h +++ b/include/DRAMUtils/memspec/MemSpec.h @@ -38,9 +38,9 @@ #include #include -#include "DRAMUtils/util/json.h" -#include "nlohmann/json.hpp" #include + +#include "DRAMUtils/util/json.h" #include "DRAMUtils/util/types.h" #include "DRAMUtils/util/id_variant.h" diff --git a/include/DRAMUtils/util/id_variant.h b/include/DRAMUtils/util/id_variant.h index 3811f4e..f02f4bd 100644 --- a/include/DRAMUtils/util/id_variant.h +++ b/include/DRAMUtils/util/id_variant.h @@ -39,8 +39,10 @@ #include #include #include -#include "types.h" -#include "nlohmann/json.hpp" + +#include +#include + #define DRAMUTILS_DECLARE_IDVARIANT(VariantName, IDFieldName, VariantTypeSequence) \ namespace detail { \ struct id_field_name_##VariantName { static constexpr char name[] = IDFieldName; }; \ @@ -71,7 +73,7 @@ class IdVariant> using VariantTypes = util::type_sequence; using Variant = util::type_sequence_id_variant_t; - using Json = nlohmann::json; + using Json = ::json_t; Variant variant; private: @@ -116,6 +118,125 @@ class IdVariant> } }; + +// Json helper functions + +template +void id_variant_from_json(const nlohmann::json& j, IdVariant& data, std::optional key) +{ + if (key) + { + // Find key + const auto it = j.find(*key); + if (it != j.end()) + { + // Key in json + if (!data.from_json(j[*key])) + throw std::bad_variant_access{}; + } + else + { + // Key not in json + throw std::bad_variant_access{}; + } + } + else { + // No key + if (!data.from_json(j)) + throw std::bad_variant_access{}; + } +} + +template +void id_variant_to_json(nlohmann::json& j, const IdVariant& data, std::optional key) +{ + if (key) + data.to_json(j[*key]); + else + data.to_json(j); + +} + + +template +constexpr bool is_id_variant = false; +template +constexpr bool is_id_variant> = true; + + +template void extended_to_json(const char* key, nlohmann::json& j, const T& value) +{ + if constexpr (is_optional) + optional_to_json(j, value, key); + else if constexpr (is_id_variant) + id_variant_to_json(j, value, key); + else if constexpr (is_variant) + variant_to_json(j, value); + else + j[key] = value; +} + +template void extended_from_json(const char* key, const nlohmann::json& j, T& value) +{ + if constexpr (is_optional) + optional_from_json(j, value, key); + else if constexpr (is_id_variant) + id_variant_from_json(j, value, key); + else if constexpr (is_variant) + variant_from_json(j, value); + else + j.at(key).get_to(value); +} + + } // namespace DRAMUtils::util + + +NLOHMANN_JSON_NAMESPACE_BEGIN + +template struct adl_serializer> +{ + static void to_json(nlohmann::json& j, const std::variant& data) + { + DRAMUtils::util::variant_to_json(j, data); + } + + static void from_json(const nlohmann::json& j, std::variant& data) + { + // Call variant_from_json for all types, only one will succeed + (DRAMUtils::util::variant_from_json(j, data), ...); + } +}; + + +template struct adl_serializer> +{ + static void to_json(nlohmann::json& j, const DRAMUtils::util::IdVariant& data) + { + DRAMUtils::util::id_variant_to_json(j, data, std::nullopt); + } + + static void from_json(const nlohmann::json& j, DRAMUtils::util::IdVariant& data) + { + // Match variant by id + DRAMUtils::util::id_variant_from_json(j, data, std::nullopt); + } +}; + + +NLOHMANN_JSON_NAMESPACE_END + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define EXTEND_JSON_TO(v1) \ + DRAMUtils::util::extended_to_json(#v1, nlohmann_json_j, nlohmann_json_t.v1); +#define EXTEND_JSON_FROM(v1) \ + DRAMUtils::util::extended_from_json(#v1, nlohmann_json_j, nlohmann_json_t.v1); + +// NOLINTEND(cppcoreguidelines-macro-usage) + + + + #endif /* DRAMUTILS_UTIL_ID_VARIANT_H */ diff --git a/include/DRAMUtils/util/json.h b/include/DRAMUtils/util/json.h index a0ef473..3d3da5e 100644 --- a/include/DRAMUtils/util/json.h +++ b/include/DRAMUtils/util/json.h @@ -43,7 +43,6 @@ #include #include #include -#include "id_variant.h" using json_t = nlohmann::json; @@ -69,41 +68,6 @@ void variant_to_json(nlohmann::json& j, const std::variant &data) std::visit([&j](const auto& v) { j = v; }, data); } -template -void id_variant_from_json(const nlohmann::json& j, IdVariant& data, std::optional key) -{ - if (key) - { - // Find key - const auto it = j.find(*key); - if (it != j.end()) - { - // Key in json - if (!data.from_json(j[*key])) - throw std::bad_variant_access{}; - } - else - { - // Key not in json - throw std::bad_variant_access{}; - } - } - else { - // No key - if (!data.from_json(j)) - throw std::bad_variant_access{}; - } -} - -template -void id_variant_to_json(nlohmann::json& j, const IdVariant& data, std::optional key) -{ - if (key) - data.to_json(j[*key]); - else - data.to_json(j); - -} template void optional_to_json(nlohmann::json& j, const std::optional& data, std::optional key) @@ -137,73 +101,15 @@ constexpr bool is_optional = false; template constexpr bool is_optional> = true; -template -constexpr bool is_id_variant = false; -template -constexpr bool is_id_variant> = true; - template constexpr bool is_variant = false; template constexpr bool is_variant> = true; -template void extended_to_json(const char* key, nlohmann::json& j, const T& value) -{ - if constexpr (is_optional) - optional_to_json(j, value, key); - else if constexpr (is_id_variant) - id_variant_to_json(j, value, key); - else if constexpr (is_variant) - variant_to_json(j, value); - else - j[key] = value; -} - -template void extended_from_json(const char* key, const nlohmann::json& j, T& value) -{ - if constexpr (is_optional) - optional_from_json(j, value, key); - else if constexpr (is_id_variant) - id_variant_from_json(j, value, key); - else if constexpr (is_variant) - variant_from_json(j, value); - else - j.at(key).get_to(value); -} - } // namespace DRAMUtils::util NLOHMANN_JSON_NAMESPACE_BEGIN -template struct adl_serializer> -{ - static void to_json(nlohmann::json& j, const std::variant& data) - { - DRAMUtils::util::variant_to_json(j, data); - } - - static void from_json(const nlohmann::json& j, std::variant& data) - { - // Call variant_from_json for all types, only one will succeed - (DRAMUtils::util::variant_from_json(j, data), ...); - } -}; - - -template struct adl_serializer> -{ - static void to_json(nlohmann::json& j, const DRAMUtils::util::IdVariant& data) - { - DRAMUtils::util::id_variant_to_json(j, data, std::nullopt); - } - - static void from_json(const nlohmann::json& j, DRAMUtils::util::IdVariant& data) - { - // Match variant by id - DRAMUtils::util::id_variant_from_json(j, data, std::nullopt); - } -}; - template struct adl_serializer> { static void to_json(json_t& j, const std::optional& opt) @@ -231,14 +137,6 @@ template struct adl_serializer> } }; -NLOHMANN_JSON_NAMESPACE_END - -// NOLINTBEGIN(cppcoreguidelines-macro-usage) - -#define EXTEND_JSON_TO(v1) \ - DRAMUtils::util::extended_to_json(#v1, nlohmann_json_j, nlohmann_json_t.v1); -#define EXTEND_JSON_FROM(v1) \ - DRAMUtils::util::extended_from_json(#v1, nlohmann_json_j, nlohmann_json_t.v1); #define NLOHMANN_JSONIFY_ALL_THINGS(Type, ...) \ inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) \ @@ -250,6 +148,7 @@ NLOHMANN_JSON_NAMESPACE_END NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(EXTEND_JSON_FROM, __VA_ARGS__)) \ } -// NOLINTEND(cppcoreguidelines-macro-usage) + +NLOHMANN_JSON_NAMESPACE_END #endif /* DRAMUTILS_UTIL_JSON_H */