diff --git a/include/glaze/json/read.hpp b/include/glaze/json/read.hpp index 6fe757159e..085e87db58 100644 --- a/include/glaze/json/read.hpp +++ b/include/glaze/json/read.hpp @@ -1808,6 +1808,35 @@ namespace glz const size_t ws_size = size_t(it - ws_start); if constexpr ((glaze_object_t || reflectable)&&num_members == 0 && Opts.error_on_unknown_keys) { + if constexpr (not tag.sv().empty()) { + if (*it == '"') { + ++it; + GLZ_INVALID_END(); + + const auto start = it; + skip_string_view(ctx, it, end); + if (bool(ctx.error)) [[unlikely]] + return; + const sv key{start, size_t(it - start)}; + ++it; + GLZ_INVALID_END(); + + if (key == tag.sv()) { + GLZ_PARSE_WS_COLON; + + read::handle_unknown(key, value, ctx, it, end); + if (bool(ctx.error)) [[unlikely]] + return; + + GLZ_SKIP_WS(); + } + else { + ctx.error = error_code::unknown_key; + return; + } + } + } + if (*it == '}') [[likely]] { GLZ_SUB_LEVEL; ++it; diff --git a/tests/json_test/json_test.cpp b/tests/json_test/json_test.cpp index 154f490e9c..3e2bf985ae 100644 --- a/tests/json_test/json_test.cpp +++ b/tests/json_test/json_test.cpp @@ -10273,44 +10273,69 @@ struct Number std::optional maximum; }; +template <> +struct glz::meta +{ + static constexpr auto value = glz::object(&Number::minimum, &Number::maximum); +}; + +struct Boolean { +}; + +template <> +struct glz::meta { + static constexpr auto value = glz::object(); +}; + struct Integer { std::optional minimum; std::optional maximum; }; -struct Array; +template <> +struct glz::meta +{ + static constexpr auto value = glz::object(&Integer::minimum, &Integer::maximum); +}; using Data = std::variant; +template <> +struct glz::meta +{ + static constexpr std::string_view tag = "type"; + static constexpr auto ids = std::array{"number", "integer"}; +}; + struct Array { Data items; }; template <> -struct glz::meta +struct glz::meta { - static constexpr auto value = glz::object(&Number::minimum, &Number::maximum); + static constexpr auto value = glz::object(&Array::items); }; +using Data2 = std::variant; + template <> -struct glz::meta -{ - static constexpr auto value = glz::object(&Integer::minimum, &Integer::maximum); +struct glz::meta { + static constexpr std::string_view tag = "type"; + static constexpr auto ids = std::array{"number", "boolean"}; }; -template <> -struct glz::meta +struct Array2 { - static constexpr auto value = glz::object(&Array::items); + Data2 items; }; template <> -struct glz::meta +struct glz::meta { - static constexpr std::string_view tag = "type"; - static constexpr auto ids = std::array{"number", "integer"}; + static constexpr auto value = glz::object(&Array2::items); }; suite tagged_variant_null_members = [] { @@ -10321,6 +10346,14 @@ suite tagged_variant_null_members = [] { expect(not glz::write_json(var, s)); expect(s == R"({"items":{"type":"number"}})") << s; }; + + "variant deduction"_test = [] { + Array2 var; + std::string str = R"({"items": { "type" : "boolean"}})"; + + auto pe = glz::read_json(var, str); + expect(not pe) << glz::format_error(pe, str); + }; }; int main()