Skip to content

Commit

Permalink
Fix for empty objects with tagged variants (#1610)
Browse files Browse the repository at this point in the history
  • Loading branch information
stephenberry authored Feb 11, 2025
1 parent a116307 commit 8f83f3b
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 12 deletions.
29 changes: 29 additions & 0 deletions include/glaze/json/read.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1808,6 +1808,35 @@ namespace glz
const size_t ws_size = size_t(it - ws_start);

if constexpr ((glaze_object_t<T> || reflectable<T>)&&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<Opts>(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<JSON>::handle_unknown<Opts>(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;
Expand Down
57 changes: 45 additions & 12 deletions tests/json_test/json_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10273,44 +10273,69 @@ struct Number
std::optional<double> maximum;
};

template <>
struct glz::meta<Number>
{
static constexpr auto value = glz::object(&Number::minimum, &Number::maximum);
};

struct Boolean {
};

template <>
struct glz::meta<Boolean> {
static constexpr auto value = glz::object();
};

struct Integer
{
std::optional<int> minimum;
std::optional<int> maximum;
};

struct Array;
template <>
struct glz::meta<Integer>
{
static constexpr auto value = glz::object(&Integer::minimum, &Integer::maximum);
};

using Data = std::variant<Number, Integer>;

template <>
struct glz::meta<Data>
{
static constexpr std::string_view tag = "type";
static constexpr auto ids = std::array{"number", "integer"};
};

struct Array
{
Data items;
};

template <>
struct glz::meta<Number>
struct glz::meta<Array>
{
static constexpr auto value = glz::object(&Number::minimum, &Number::maximum);
static constexpr auto value = glz::object(&Array::items);
};

using Data2 = std::variant<Number, Boolean>;

template <>
struct glz::meta<Integer>
{
static constexpr auto value = glz::object(&Integer::minimum, &Integer::maximum);
struct glz::meta<Data2> {
static constexpr std::string_view tag = "type";
static constexpr auto ids = std::array{"number", "boolean"};
};

template <>
struct glz::meta<Array>
struct Array2
{
static constexpr auto value = glz::object(&Array::items);
Data2 items;
};

template <>
struct glz::meta<Data>
struct glz::meta<Array2>
{
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 = [] {
Expand All @@ -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()
Expand Down

0 comments on commit 8f83f3b

Please sign in to comment.