diff --git a/docs/mkdocs/docs/api/basic_json/parser_callback_t.md b/docs/mkdocs/docs/api/basic_json/parser_callback_t.md index 460f69cbb..da23e9bc2 100644 --- a/docs/mkdocs/docs/api/basic_json/parser_callback_t.md +++ b/docs/mkdocs/docs/api/basic_json/parser_callback_t.md @@ -29,7 +29,14 @@ Discarding a value (i.e., returning `#!cpp false`) has different effects dependi called: - Discarded values in structured types are skipped. That is, the parser will behave as if the discarded value was never - read. + read. This holds for every value type and for both kinds of parent: a discarded element is removed from the + surrounding array, and a discarded member is removed from the surrounding object together with its key. +- Arrays and objects can be discarded either at their `parse_event_t::array_start`/`parse_event_t::object_start` event + or at their `parse_event_t::array_end`/`parse_event_t::object_end` event, and both remove the whole value. Discarding + it at the start event also means the callback is called neither for the content of the value nor for its matching end + event. +- Discarding a `parse_event_t::key` event discards the whole object member. The callback is still called for the + associated value, but its return value has no further effect. - In case a value outside a structured type is skipped, it is replaced with `null`. This case happens if the top-level element is skipped. @@ -49,7 +56,7 @@ called: ## Return value Whether the JSON value which called the function during parsing should be kept (`#!cpp true`) or not (`#!cpp false`). In -the latter case, it is either skipped completely or replaced by an empty discarded object. +the latter case, it is skipped completely, or replaced by `null` if it is the top-level value. ## Examples @@ -68,6 +75,21 @@ the latter case, it is either skipped completely or replaced by an empty discard --8<-- "examples/parse__string__parser_callback_t.output" ``` +??? example + + The example below shows where discarded values are removed. The array and the number are discarded in different + ways, but in each case the parse result contains neither the value nor its key. + + ```cpp + --8<-- "examples/parser_callback_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parser_callback_t.output" + ``` + ## See also - [parse](parse.md) deserialize from a compatible input @@ -76,3 +98,5 @@ the latter case, it is either skipped completely or replaced by an empty discard ## Version history - Added in version 1.0.0. +- Fixed in version 3.13.0 to also remove discarded values from a parent object; before, discarding an array or a value + stored under an object key left a discarded member behind, which made the parse result serialize to invalid JSON. diff --git a/docs/mkdocs/docs/examples/parser_callback_t.cpp b/docs/mkdocs/docs/examples/parser_callback_t.cpp new file mode 100644 index 000000000..45794cca6 --- /dev/null +++ b/docs/mkdocs/docs/examples/parser_callback_t.cpp @@ -0,0 +1,47 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // a JSON text with an array and a number inside an object + auto text = R"({"IDs": [116, 943], "Width": 800})"; + + // discard the array when the parser reads its opening bracket + json j_array_start = json::parse(text, [](int /*depth*/, json::parse_event_t event, json & /*parsed*/) + { + return event != json::parse_event_t::array_start; + }); + + // discard the same array when the parser reads its closing bracket + json j_array_end = json::parse(text, [](int /*depth*/, json::parse_event_t event, json & /*parsed*/) + { + return event != json::parse_event_t::array_end; + }); + + // discard the number, but keep its key + json j_value = json::parse(text, [](int /*depth*/, json::parse_event_t event, json & parsed) + { + return !(event == json::parse_event_t::value && parsed == json(800)); + }); + + // discard the key of the number + json j_key = json::parse(text, [](int /*depth*/, json::parse_event_t event, json & parsed) + { + return !(event == json::parse_event_t::key && parsed == json("Width")); + }); + + // discard the top-level object + json j_root = json::parse(text, [](int /*depth*/, json::parse_event_t event, json & /*parsed*/) + { + return event != json::parse_event_t::object_end; + }); + + // in every case, the discarded value is removed together with its key + std::cout << j_array_start << '\n' + << j_array_end << '\n' + << j_value << '\n' + << j_key << '\n' + << j_root << '\n'; +} diff --git a/docs/mkdocs/docs/examples/parser_callback_t.output b/docs/mkdocs/docs/examples/parser_callback_t.output new file mode 100644 index 000000000..00c19a939 --- /dev/null +++ b/docs/mkdocs/docs/examples/parser_callback_t.output @@ -0,0 +1,5 @@ +{"Width":800} +{"Width":800} +{"IDs":[116,943]} +{"IDs":[116,943]} +null