From d4a49deb838510d409f2c6711da9f576777ffc51 Mon Sep 17 00:00:00 2001 From: "marek.piotrowski" Date: Thu, 20 Jul 2023 00:10:40 +0200 Subject: [PATCH] Added static annotations --- example/main.cpp | 7 +++---- include/nlohmann/detail/macro_scope.hpp | 18 +++++++++++++--- include/nlohmann/detail/output/serializer.hpp | 8 +++++++ include/nlohmann/json.hpp | 21 +++++++++++++++++++ 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/example/main.cpp b/example/main.cpp index 8c7ea08b3..8de05924b 100644 --- a/example/main.cpp +++ b/example/main.cpp @@ -14,10 +14,9 @@ private: public: ExampleClass() = default; - // NLOHMANN_DEFINE_TYPE_INTRUSIVE(ExampleClass, property1, property2, property3, property4, property5); - NLOHMANN_DEFINE_TYPE_INTRUSIVE_ANNOTATED(ExampleClass, property1, "comment1", - property2, "comment2"); + property2, "comment2", + property3, "comment3"); }; int main() { @@ -25,6 +24,6 @@ int main() { ExampleClass ec; nlohmann::json j = ec; - std::cout << j.dump() << std::endl; + std::cout << j.dump_annotated() << std::endl; return 0; } \ No newline at end of file diff --git a/include/nlohmann/detail/macro_scope.hpp b/include/nlohmann/detail/macro_scope.hpp index 53c23870a..54f9190b6 100644 --- a/include/nlohmann/detail/macro_scope.hpp +++ b/include/nlohmann/detail/macro_scope.hpp @@ -385,8 +385,9 @@ #define NLOHMANN_JSON_ANNOTATED_EXPAND( x ) x -#define NLOHMANN_JSON_ANNOTATED_GET_MACRO(_1, _2, _3, _4, _5, NAME,...) NAME +#define NLOHMANN_JSON_ANNOTATED_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, NAME,...) NAME #define NLOHMANN_JSON_ANNOTATED_PASTE(...) NLOHMANN_JSON_ANNOTATED_EXPAND(NLOHMANN_JSON_ANNOTATED_GET_MACRO(__VA_ARGS__, \ + NLOHMANN_JSON_ANNOTATED_PASTE7, \ NLOHMANN_JSON_ANNOTATED_PASTE5, \ NLOHMANN_JSON_ANNOTATED_PASTE2, \ NLOHMANN_JSON_ANNOTATED_PASTE1)(__VA_ARGS__)) @@ -394,8 +395,10 @@ // #define NLOHMANN_JSON_ANNOTATED_PASTE3(func, v1, w1, v2, w2) NLOHMANN_JSON_ANNOTATED_PASTE2(func, v1, w1) NLOHMANN_JSON_ANNOTATED_PASTE2(func, v2, w2) // #define NLOHMANN_JSON_ANNOTATED_PASTE4(func, v1, w1, v2, w2, v3, w3) NLOHMANN_JSON_ANNOTATED_PASTE2(func, v1, w1) NLOHMANN_JSON_ANNOTATED_PASTE3(func, v2, w2, v3, w3) #define NLOHMANN_JSON_ANNOTATED_PASTE5(func, v1, w1, v2, w2) NLOHMANN_JSON_ANNOTATED_PASTE2(func, v1, w1) NLOHMANN_JSON_ANNOTATED_PASTE2(func, v2, w2) +#define NLOHMANN_JSON_ANNOTATED_PASTE7(func, v1, w1, v2, w2, v3, w3) NLOHMANN_JSON_ANNOTATED_PASTE2(func, v1, w1) NLOHMANN_JSON_ANNOTATED_PASTE5(func, v2, w2, v3, w3) -#define NLOHMANN_JSON_ANNOTATED_TO(v1, w1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; nlohmann_json_j[#v1].annotate(w1); +#define NLOHMANN_JSON_ANNOTATED_TO(v1, w1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; +// #define NLOHMANN_EXPAND_ANNOTATION(v1, w1) static constexpr char annotation_##v1[] = w1; #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); #define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1); @@ -409,8 +412,17 @@ friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } +#define TERNARY_EXPAND1(v1, w1) (property == #v1 ? w1 : "") +#define TERNARY_EXPAND2(v1, w1, v2, w2) (property == #v2 ? w2 : TERNARY_EXPAND1(v1, w1)) +#define TERNARY_EXPAND3(v1, w1, v2, w2, v3, w3) (property == #v3 ? w3 : TERNARY_EXPAND2(v1, w1, v2, w2)) +#define TERNARY_NOT_ALLOWED + +#define GET_TERNARY_EXPAND_MACRO(_1,_2,_3,_4,_5,_6,NAME,...) NAME +#define TERNARY_EXPAND(...) GET_TERNARY_EXPAND_MACRO(__VA_ARGS__, TERNARY_EXPAND3, TERNARY_NOT_ALLOWED, TERNARY_EXPAND2, TERNARY_NOT_ALLOWED, TERNARY_EXPAND1)(__VA_ARGS__) + #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ANNOTATED(Type, ...) \ - friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_ANNOTATED_EXPAND(NLOHMANN_JSON_ANNOTATED_PASTE(NLOHMANN_JSON_ANNOTATED_TO, __VA_ARGS__)) } + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_ANNOTATED_EXPAND(NLOHMANN_JSON_ANNOTATED_PASTE(NLOHMANN_JSON_ANNOTATED_TO, __VA_ARGS__)) } \ + static std::string get_annotation(const std::string& property) { return TERNARY_EXPAND(__VA_ARGS__); } #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \ friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ diff --git a/include/nlohmann/detail/output/serializer.hpp b/include/nlohmann/detail/output/serializer.hpp index f17b89c63..a05edb12a 100644 --- a/include/nlohmann/detail/output/serializer.hpp +++ b/include/nlohmann/detail/output/serializer.hpp @@ -373,6 +373,14 @@ class serializer } } + template + void dump_annotated(const BasicJsonType& val, + const bool pretty_print, + const bool ensure_ascii, + const unsigned int indent_step, + const unsigned int current_indent = 0) { + o->write_characters(UnderlyingType::get_annotation("property3").c_str(), UnderlyingType::get_annotation("property1").size()); + } JSON_PRIVATE_UNLESS_TESTED: /*! @brief dump escaped string diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index eedf27fbc..4ccdad5a6 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -1289,6 +1289,27 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } + template + string_t dump_annotated(const int indent = -1, + const char indent_char = ' ', + const bool ensure_ascii = false, + const error_handler_t error_handler = error_handler_t::strict) const + { + string_t result; + serializer s(detail::output_adapter(result), indent_char, error_handler); + + if (indent >= 0) + { + s.template dump_annotated(*this, true, ensure_ascii, static_cast(indent)); + } + else + { + s.template dump_annotated(*this, false, ensure_ascii, 0); + } + + return result; + } + /// @brief return the type of the JSON value (explicit) /// @sa https://json.nlohmann.me/api/basic_json/type/ constexpr value_t type() const noexcept