mirror of
https://github.com/nlohmann/json.git
synced 2026-10-03 05:00:30 +00:00
Review and extend the documentation, and check it in CI (#5638)
* Review and extend the documentation, and check it in CI A review of all documentation pages found factual errors, dead links, missing cross-references, and gaps in examples. This fixes them and adds checks so the same problems are caught automatically. Fixes: - wrong signatures and version histories (operator!= C++20 member, binary() subtype type, get<PointerType>(), JSON_NO_THREAD_LOCAL, ...) - stale descriptions (number parsing since #5283, UBJSON table, SAX example that no longer compiled, tsl::ordered_map advice) - dead internal and external links; repology.org badges (the domain is suspended) replaced by badges that query the registries directly - deprecation notes link the migration guide; the guide itself fixed Additions: - "See also" sections, cross-references, 25 runnable examples, 12 Mermaid diagrams, new API pages for json_pointer::operator<=> and byte_container_with_subtype::operator==/!= - landing page, guides for untrusted input and performance - "unreleased" badge after versions newer than the latest release Checks: - strict documentation build (broken links/anchors fail it); CI and the publish workflow fetch the full history the build needs - weekly external link check, Mermaid syntax check in CI - check_structure.py: example titles, heading levels, alt texts, header links, docset index coverage; its unused-example check works again - all examples produce the same output on every platform Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Keep the customer links that could not be fixed A dead link on the customers page is still the evidence of where the use of the library was documented. Keep the original URLs of the entries without a working replacement (Marne, Cisco Webex Desk Camera, Philips Hue, CyberArk) and exclude exactly these URLs from the link check. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Correct the duplicate-key recipe's claim about SAX positions The SAX interface's key() receives no position either; only parse_error() does. Also note that the recipe does not report the path to the repeated key (see discussion #5085). Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Say the library is available as a single header and mention json_fwd.hpp Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Correct documentation errors found while hunting for bugs - patch/patch_inplace: list the JSON pointer errors parse_error.106-109 and out_of_range.402/404, and quote the actual parse_error.105 message. - unflatten: list parse_error.106/107/108 and out_of_range.404. - to_bson: list out_of_range.415 (binary subtype above 255) and note that 412 and 415 are new in 3.13.0. - to_string: state that string_t must be convertible to std::string, also in the StringType requirements table. - JSON Lines: a `while (input >> j)` loop also throws after the last value for concatenated JSON values; show a loop that works for both. - BON8: a string gets 0xFF only if nothing follows it in the message; a string at the end of an array or object is ended by 0xFE. - custom_string_type.hpp: add operator+=(char), which the "Always required" list asks for (json_pointer::to_string, flatten, unflatten, and diff did not compile), and an ADL int_to_string for diff and items. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Cache the release headers with functools.lru_cache Codacy (Pylint) flagged the mutable default argument that header() used as its cache. functools.lru_cache keeps the same memoization without it. The script's output is unchanged. Signed-off-by: Niels Lohmann <mail@nlohmann.me> --------- Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
int main()
|
||||
{
|
||||
// a buffer containing a JSON text followed by more data
|
||||
std::vector<std::uint8_t> input = {'[', '1', ',', '2', ',', '3', ']', 'o', 't', 'h', 'e', 'r'};
|
||||
|
||||
std::cout << std::boolalpha
|
||||
<< json::accept(input.begin(), input.begin() + 7) << ' '
|
||||
<< json::accept(input.begin(), input.end()) << '\n';
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
true false
|
||||
@@ -0,0 +1,22 @@
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
using ordered_json = nlohmann::ordered_json;
|
||||
|
||||
int main()
|
||||
{
|
||||
// create an ordered_json value; insertion order is preserved
|
||||
ordered_json oj = {{"c", 3}, {"a", 1}, {"b", 2}};
|
||||
|
||||
// convert to json -- overload (4) is used; keys end up sorted
|
||||
json j(oj);
|
||||
|
||||
// convert back to ordered_json -- the original insertion order is lost,
|
||||
// because it was already given up when converting to json
|
||||
ordered_json oj2(j);
|
||||
|
||||
std::cout << oj << '\n';
|
||||
std::cout << j << '\n';
|
||||
std::cout << oj2 << '\n';
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{"c":3,"a":1,"b":2}
|
||||
{"a":1,"b":2,"c":3}
|
||||
{"a":1,"b":2,"c":3}
|
||||
@@ -44,7 +44,7 @@ int main()
|
||||
// create an object from std::unordered_multimap
|
||||
std::unordered_multimap<std::string, bool> c_ummap
|
||||
{
|
||||
{"one", true}, {"two", true}, {"three", false}, {"three", true}
|
||||
{"one", true}, {"two", true}, {"three", false}, {"three", false}
|
||||
};
|
||||
json j_ummap(c_ummap); // only one entry for key "three" is used
|
||||
|
||||
@@ -92,7 +92,7 @@ int main()
|
||||
json j_set(c_set); // only one entry for "one" is used
|
||||
|
||||
// create an array from std::unordered_set
|
||||
std::unordered_set<std::string> c_uset {"one", "two", "three", "four", "one"};
|
||||
std::unordered_set<std::string> c_uset {"one", "one"};
|
||||
json j_uset(c_uset); // only one entry for "one" is used
|
||||
|
||||
// create an array from std::multiset
|
||||
@@ -100,7 +100,7 @@ int main()
|
||||
json j_mset(c_mset); // both entries for "one" are used
|
||||
|
||||
// create an array from std::unordered_multiset
|
||||
std::unordered_multiset<std::string> c_umset {"one", "two", "one", "four"};
|
||||
std::unordered_multiset<std::string> c_umset {"one", "one"};
|
||||
json j_umset(c_umset); // both entries for "one" are used
|
||||
|
||||
// serialize the JSON arrays
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
[12345678909876,23456789098765,34567890987654,45678909876543]
|
||||
[1,2,3,4]
|
||||
["four","one","three","two"]
|
||||
["four","three","two","one"]
|
||||
["one"]
|
||||
["four","one","one","two"]
|
||||
["four","two","one","one"]
|
||||
["one","one"]
|
||||
|
||||
"The quick brown fox jumps over the lazy dog."
|
||||
"The quick brown fox jumps over the lazy dog."
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
// define a byte container based on std::vector
|
||||
using byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;
|
||||
|
||||
int main()
|
||||
{
|
||||
std::vector<std::uint8_t> bytes = {{0xca, 0xfe, 0xba, 0xbe}};
|
||||
|
||||
// create containers without and with a subtype
|
||||
auto c1 = byte_container_with_subtype(bytes);
|
||||
auto c2 = byte_container_with_subtype(bytes);
|
||||
auto c3 = byte_container_with_subtype(bytes, 42);
|
||||
auto c4 = byte_container_with_subtype(bytes, 42);
|
||||
auto c5 = byte_container_with_subtype(bytes, 23);
|
||||
|
||||
std::cout << std::boolalpha
|
||||
<< "c1 == c2: " << (c1 == c2) << '\n'
|
||||
<< "c1 == c3: " << (c1 == c3) << '\n'
|
||||
<< "c3 == c4: " << (c3 == c4) << '\n'
|
||||
<< "c3 == c5: " << (c3 == c5) << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
c1 == c2: true
|
||||
c1 == c3: false
|
||||
c3 == c4: true
|
||||
c3 == c5: false
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
// define a byte container based on std::vector
|
||||
using byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;
|
||||
|
||||
int main()
|
||||
{
|
||||
std::vector<std::uint8_t> bytes = {{0xca, 0xfe, 0xba, 0xbe}};
|
||||
|
||||
// create containers without and with a subtype
|
||||
auto c1 = byte_container_with_subtype(bytes);
|
||||
auto c2 = byte_container_with_subtype(bytes);
|
||||
auto c3 = byte_container_with_subtype(bytes, 42);
|
||||
auto c4 = byte_container_with_subtype(bytes, 42);
|
||||
auto c5 = byte_container_with_subtype(bytes, 23);
|
||||
|
||||
std::cout << std::boolalpha
|
||||
<< "c1 != c2: " << (c1 != c2) << '\n'
|
||||
<< "c1 != c3: " << (c1 != c3) << '\n'
|
||||
<< "c3 != c4: " << (c3 != c4) << '\n'
|
||||
<< "c3 != c5: " << (c3 != c5) << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
c1 != c2: false
|
||||
c1 != c3: true
|
||||
c3 != c4: false
|
||||
c3 != c5: true
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
@@ -8,10 +9,10 @@
|
||||
// and nothing more of std::string's interface.
|
||||
//
|
||||
// Covers the "Always required" members, the extras needed for the binary
|
||||
// formats, and the extras needed for JSON Pointer / flatten / unflatten /
|
||||
// diff. Extending it further (e.g. for std::hash<basic_json> or to_bson) is
|
||||
// a matter of adding the extra members listed in the "Required for other
|
||||
// functionality" table.
|
||||
// formats, JSON Pointer / flatten / unflatten, and the int_to_string overload
|
||||
// needed for diff and items. Extending it further (e.g. for
|
||||
// std::hash<basic_json> or to_bson) is a matter of adding the extra members
|
||||
// listed in the "Required for other functionality" table.
|
||||
//
|
||||
// See https://json.nlohmann.me/features/types/template_parameters/#stringtype
|
||||
class custom_string_type
|
||||
@@ -93,6 +94,11 @@ class custom_string_type
|
||||
data_.append(other.data_);
|
||||
return *this;
|
||||
}
|
||||
custom_string_type& operator+=(char c)
|
||||
{
|
||||
data_.push_back(c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_type find_first_of(char c, size_type pos = 0) const
|
||||
{
|
||||
@@ -116,6 +122,12 @@ class custom_string_type
|
||||
return data_.end();
|
||||
}
|
||||
|
||||
// found by ADL; converts array indices to keys in diff and items
|
||||
friend void int_to_string(custom_string_type& target, std::size_t value)
|
||||
{
|
||||
target.data_ = std::to_string(value);
|
||||
}
|
||||
|
||||
friend bool operator==(const custom_string_type& lhs, const custom_string_type& rhs)
|
||||
{
|
||||
return lhs.data_ == rhs.data_;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
int main()
|
||||
{
|
||||
// create a JSON value with an empty object and an empty array
|
||||
json j =
|
||||
{
|
||||
{"empty_object", json::object()},
|
||||
{"empty_array", json::array()},
|
||||
{"name", "Niels"}
|
||||
};
|
||||
|
||||
// call flatten()
|
||||
json flattened = j.flatten();
|
||||
std::cout << std::setw(4) << flattened << "\n\n";
|
||||
|
||||
// the empty containers cannot be restored by unflatten()
|
||||
std::cout << std::setw(4) << flattened.unflatten() << '\n';
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"/empty_array": null,
|
||||
"/empty_object": null,
|
||||
"/name": "Niels"
|
||||
}
|
||||
|
||||
{
|
||||
"empty_array": null,
|
||||
"empty_object": null,
|
||||
"name": "Niels"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
using ordered_json = nlohmann::ordered_json;
|
||||
|
||||
int main()
|
||||
{
|
||||
// create a JSON value
|
||||
json j = {{"one", 1}, {"two", 2}, {"three", 3}};
|
||||
|
||||
// convert to a different basic_json specialization
|
||||
ordered_json oj = j.get<ordered_json>();
|
||||
|
||||
std::cout << j << '\n';
|
||||
std::cout << oj << '\n';
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
{"one":1,"three":3,"two":2}
|
||||
{"one":1,"three":3,"two":2}
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
@@ -29,7 +29,7 @@ int main()
|
||||
auto v5 = json_types["number"]["floating-point"].get<int>();
|
||||
auto v6 = json_types["string"].get<std::string>();
|
||||
auto v7 = json_types["array"].get<std::vector<short>>();
|
||||
auto v8 = json_types.get<std::unordered_map<std::string, json>>();
|
||||
auto v8 = json_types.get<std::map<std::string, json>>();
|
||||
|
||||
// print the conversion results
|
||||
std::cout << v1 << '\n';
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
Hello, world!
|
||||
1 2 3 4 5
|
||||
|
||||
number: {"floating-point":17.23,"integer":42}
|
||||
null: null
|
||||
string: "Hello, world!"
|
||||
boolean: true
|
||||
array: [1,2,3,4,5]
|
||||
boolean: true
|
||||
null: null
|
||||
number: {"floating-point":17.23,"integer":42}
|
||||
string: "Hello, world!"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
@@ -28,7 +28,7 @@ int main()
|
||||
int v5;
|
||||
std::string v6;
|
||||
std::vector<short> v7;
|
||||
std::unordered_map<std::string, json> v8;
|
||||
std::map<std::string, json> v8;
|
||||
|
||||
// use explicit conversions
|
||||
json_types["boolean"].get_to(v1);
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
Hello, world!
|
||||
1 2 3 4 5
|
||||
|
||||
number: {"floating-point":17.23,"integer":42}
|
||||
null: null
|
||||
string: "Hello, world!"
|
||||
boolean: true
|
||||
array: [1,2,3,4,5]
|
||||
boolean: true
|
||||
null: null
|
||||
number: {"floating-point":17.23,"integer":42}
|
||||
string: "Hello, world!"
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
int main()
|
||||
{
|
||||
// parsing invalid JSON without exceptions yields a discarded value
|
||||
json j_invalid = json::parse("[1,2,3", nullptr, false);
|
||||
|
||||
// a callback that discards the top-level value does not leave it
|
||||
// "discarded" -- it is replaced by null instead
|
||||
json j_discarded_by_callback = json::parse("[1,2,3]", [](int /*depth*/, json::parse_event_t event, json& /*parsed*/)
|
||||
{
|
||||
return event != json::parse_event_t::array_start;
|
||||
});
|
||||
|
||||
std::cout << std::boolalpha;
|
||||
std::cout << "j_invalid.is_discarded() = " << j_invalid.is_discarded() << '\n';
|
||||
std::cout << "j_discarded_by_callback = " << j_discarded_by_callback << '\n';
|
||||
std::cout << "j_discarded_by_callback.is_discarded() = " << j_discarded_by_callback.is_discarded() << '\n';
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
j_invalid.is_discarded() = true
|
||||
j_discarded_by_callback = null
|
||||
j_discarded_by_callback.is_discarded() = false
|
||||
@@ -0,0 +1,32 @@
|
||||
#include <compare>
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
const char* to_string(const std::strong_ordering& so)
|
||||
{
|
||||
if (std::is_lt(so))
|
||||
{
|
||||
return "less";
|
||||
}
|
||||
else if (std::is_gt(so))
|
||||
{
|
||||
return "greater";
|
||||
}
|
||||
return "equal";
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// different JSON pointers
|
||||
json::json_pointer ptr1("/a/b");
|
||||
json::json_pointer ptr2("/a/c");
|
||||
json::json_pointer ptr3("/a/b/c");
|
||||
json::json_pointer ptr4("/a/b");
|
||||
|
||||
// 3-way compare JSON pointers
|
||||
std::cout << "\"" << ptr1 << "\" <=> \"" << ptr2 << "\": " << to_string(ptr1 <=> ptr2) << '\n' // *NOPAD*
|
||||
<< "\"" << ptr1 << "\" <=> \"" << ptr3 << "\": " << to_string(ptr1 <=> ptr3) << '\n' // *NOPAD*
|
||||
<< "\"" << ptr1 << "\" <=> \"" << ptr4 << "\": " << to_string(ptr1 <=> ptr4) << std::endl; // *NOPAD*
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
"/a/b" <=> "/a/c": less
|
||||
"/a/b" <=> "/a/b/c": less
|
||||
"/a/b" <=> "/a/b": equal
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
@@ -29,7 +29,7 @@ int main()
|
||||
int v5 = json_types["number"]["floating-point"];
|
||||
std::string v6 = json_types["string"];
|
||||
std::vector<short> v7 = json_types["array"];
|
||||
std::unordered_map<std::string, json> v8 = json_types;
|
||||
std::map<std::string, json> v8 = json_types;
|
||||
|
||||
// print the conversion results
|
||||
std::cout << v1 << '\n';
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
Hello, world!
|
||||
1 2 3 4 5
|
||||
|
||||
number: {"floating-point":17.23,"integer":42}
|
||||
null: null
|
||||
string: "Hello, world!"
|
||||
boolean: true
|
||||
array: [1,2,3,4,5]
|
||||
boolean: true
|
||||
null: null
|
||||
number: {"floating-point":17.23,"integer":42}
|
||||
string: "Hello, world!"
|
||||
[json.exception.type_error.302] type must be boolean, but is string
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
// translate a parse_event_t to a human-readable name
|
||||
std::string event_name(json::parse_event_t event)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case json::parse_event_t::object_start:
|
||||
return "object_start";
|
||||
case json::parse_event_t::object_end:
|
||||
return "object_end";
|
||||
case json::parse_event_t::array_start:
|
||||
return "array_start";
|
||||
case json::parse_event_t::array_end:
|
||||
return "array_end";
|
||||
case json::parse_event_t::key:
|
||||
return "key";
|
||||
case json::parse_event_t::value:
|
||||
return "value";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// a small JSON text
|
||||
auto text = R"({"pi": 3.141, "numbers": [1, 2]})";
|
||||
|
||||
// parse the text and report every event together with its depth;
|
||||
// returning true keeps every value unchanged
|
||||
json j = json::parse(text, [](int depth, json::parse_event_t event, json& /*parsed*/)
|
||||
{
|
||||
std::cout << depth << " " << event_name(event) << '\n';
|
||||
return true;
|
||||
});
|
||||
|
||||
// the callback did not change anything, so the parsed value is unaffected
|
||||
std::cout << j << '\n';
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
0 object_start
|
||||
1 key
|
||||
1 value
|
||||
1 key
|
||||
1 array_start
|
||||
2 value
|
||||
2 value
|
||||
1 array_end
|
||||
0 object_end
|
||||
{"numbers":[1,2],"pi":3.141}
|
||||
@@ -0,0 +1,36 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
using namespace nlohmann::literals;
|
||||
|
||||
int main()
|
||||
{
|
||||
// the original document
|
||||
json doc = R"(
|
||||
{
|
||||
"a": { "b": 1 }
|
||||
}
|
||||
)"_json;
|
||||
|
||||
// a patch that tries to move "/a" into one of its own children
|
||||
json patch = R"(
|
||||
[
|
||||
{ "op": "move", "from": "/a", "path": "/a/b" }
|
||||
]
|
||||
)"_json;
|
||||
|
||||
// exception out_of_range.414
|
||||
try
|
||||
{
|
||||
json patched_doc = doc.patch(patch);
|
||||
}
|
||||
catch (const json::out_of_range& e)
|
||||
{
|
||||
std::cout << e.what() << '\n';
|
||||
}
|
||||
|
||||
// the original document is unchanged
|
||||
std::cout << std::setw(4) << doc << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
[json.exception.out_of_range.414] cannot move value: 'from' path '/a' is a proper prefix of 'path' '/a/b'
|
||||
{
|
||||
"a": {
|
||||
"b": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
using namespace nlohmann::literals;
|
||||
|
||||
int main()
|
||||
{
|
||||
// the original document
|
||||
json doc = R"(
|
||||
{
|
||||
"a": 1,
|
||||
"b": 2
|
||||
}
|
||||
)"_json;
|
||||
|
||||
// a patch whose second operation fails
|
||||
json patch = R"(
|
||||
[
|
||||
{ "op": "replace", "path": "/a", "value": 99 },
|
||||
{ "op": "remove", "path": "/nonexistent" }
|
||||
]
|
||||
)"_json;
|
||||
|
||||
// exception out_of_range.403
|
||||
try
|
||||
{
|
||||
doc.patch_inplace(patch);
|
||||
}
|
||||
catch (const json::out_of_range& e)
|
||||
{
|
||||
std::cout << e.what() << '\n';
|
||||
}
|
||||
|
||||
// the first operation has already been applied to doc
|
||||
std::cout << std::setw(4) << doc << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
[json.exception.out_of_range.403] key 'nonexistent' not found
|
||||
{
|
||||
"a": 99,
|
||||
"b": 2
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
// a DOM parser that reports parse errors instead of throwing
|
||||
class sax_no_exception : public nlohmann::detail::json_sax_dom_parser<json, nlohmann::detail::string_input_adapter_type>
|
||||
{
|
||||
public:
|
||||
explicit sax_no_exception(json& j)
|
||||
: nlohmann::detail::json_sax_dom_parser<json, nlohmann::detail::string_input_adapter_type>(j, false)
|
||||
{}
|
||||
|
||||
bool parse_error(std::size_t position,
|
||||
const std::string& last_token,
|
||||
const json::exception& ex)
|
||||
{
|
||||
std::cout << "parse error at input byte " << position << "\n"
|
||||
<< ex.what() << "\n"
|
||||
<< "last read: \"" << last_token << "\""
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
std::string myinput = "[1,2,3,]";
|
||||
|
||||
json result;
|
||||
sax_no_exception sax(result);
|
||||
|
||||
bool parse_result = json::sax_parse(myinput, &sax);
|
||||
if (!parse_result)
|
||||
{
|
||||
std::cout << "parsing unsuccessful!" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "parsed value: " << result << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
parse error at input byte 8
|
||||
[json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal
|
||||
last read: "3,]"
|
||||
parsing unsuccessful!
|
||||
parsed value: [1,2,3]
|
||||
@@ -0,0 +1,20 @@
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
int main()
|
||||
{
|
||||
// create a non-empty JSON array
|
||||
json j = {1, 2, 3};
|
||||
|
||||
// exception other_error.502
|
||||
try
|
||||
{
|
||||
json::to_bjdata(j, false, true);
|
||||
}
|
||||
catch (const json::other_error& e)
|
||||
{
|
||||
std::cout << e.what() << '\n';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
[json.exception.other_error.502] use_type requires use_size = true
|
||||
@@ -0,0 +1,22 @@
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
int main()
|
||||
{
|
||||
// create a JSON string that is not valid UTF-8
|
||||
std::string invalid_utf8;
|
||||
invalid_utf8.push_back(static_cast<char>(0xFF));
|
||||
json j = invalid_utf8;
|
||||
|
||||
// exception type_error.316
|
||||
try
|
||||
{
|
||||
json::to_bon8(j);
|
||||
}
|
||||
catch (const json::type_error& e)
|
||||
{
|
||||
std::cout << e.what() << '\n';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
[json.exception.type_error.316] invalid UTF-8 byte at index 0: 0xFF
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
int main()
|
||||
{
|
||||
// create a JSON object whose key contains a null byte (U+0000)
|
||||
std::string key = "ab";
|
||||
key.push_back('\0');
|
||||
key.push_back('c');
|
||||
json j = {{key, 1}};
|
||||
|
||||
// exception out_of_range.409
|
||||
try
|
||||
{
|
||||
json::to_bson(j);
|
||||
}
|
||||
catch (const json::out_of_range& e)
|
||||
{
|
||||
std::cout << e.what() << '\n';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
[json.exception.out_of_range.409] BSON key cannot contain code point U+0000 (at byte 2)
|
||||
@@ -0,0 +1,20 @@
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
int main()
|
||||
{
|
||||
// create a JSON value with a binary subtype that exceeds 255
|
||||
json j = json::binary({1, 2, 3}, 300);
|
||||
|
||||
// exception out_of_range.415
|
||||
try
|
||||
{
|
||||
json::to_msgpack(j);
|
||||
}
|
||||
catch (const json::out_of_range& e)
|
||||
{
|
||||
std::cout << e.what() << '\n';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
[json.exception.out_of_range.415] subtype 300 is too large for the MessagePack ext type (max 255)
|
||||
@@ -0,0 +1,20 @@
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
int main()
|
||||
{
|
||||
// create a non-empty JSON array
|
||||
json j = {1, 2, 3};
|
||||
|
||||
// exception other_error.502
|
||||
try
|
||||
{
|
||||
json::to_ubjson(j, false, true);
|
||||
}
|
||||
catch (const json::other_error& e)
|
||||
{
|
||||
std::cout << e.what() << '\n';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
[json.exception.other_error.502] use_type requires use_size = true
|
||||
@@ -0,0 +1,33 @@
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
int main()
|
||||
{
|
||||
// create a JSON object with a string value
|
||||
json j = {{"name", "the good"}};
|
||||
|
||||
// exception type_error.302
|
||||
try
|
||||
{
|
||||
int v = j.value("name", 0);
|
||||
std::cout << v << '\n';
|
||||
}
|
||||
catch (const json::type_error& e)
|
||||
{
|
||||
std::cout << e.what() << '\n';
|
||||
}
|
||||
|
||||
// exception type_error.306
|
||||
try
|
||||
{
|
||||
json str = "I am a string";
|
||||
auto v = str.value("name", 0);
|
||||
std::cout << v << '\n';
|
||||
}
|
||||
catch (const json::type_error& e)
|
||||
{
|
||||
std::cout << e.what() << '\n';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
[json.exception.type_error.302] type must be number, but is string
|
||||
[json.exception.type_error.306] cannot use value() with string
|
||||
Reference in New Issue
Block a user