diff --git a/doc/examples/json_pointer.cpp b/doc/examples/json_pointer.cpp new file mode 100644 index 00000000..140eac3b --- /dev/null +++ b/doc/examples/json_pointer.cpp @@ -0,0 +1,46 @@ +#include + +using json = nlohmann::json; + +int main() +{ + // correct JSON pointers + json::json_pointer p1; + json::json_pointer p2(""); + json::json_pointer p3("/"); + json::json_pointer p4("//"); + json::json_pointer p5("/foo/bar"); + json::json_pointer p6("/foo/bar/-"); + json::json_pointer p7("/foo/~0"); + json::json_pointer p8("/foo/~1"); + + // error: JSON pointer does not begin with a slash + try + { + json::json_pointer p9("foo"); + } + catch (std::domain_error& e) + { + std::cout << "domain_error: " << e.what() << '\n'; + } + + // error: JSON pointer uses escape symbol ~ not followed by 0 or 1 + try + { + json::json_pointer p10("/foo/~"); + } + catch (std::domain_error& e) + { + std::cout << "domain_error: " << e.what() << '\n'; + } + + // error: JSON pointer uses escape symbol ~ not followed by 0 or 1 + try + { + json::json_pointer p11("/foo/~3"); + } + catch (std::domain_error& e) + { + std::cout << "domain_error: " << e.what() << '\n'; + } +} diff --git a/doc/examples/json_pointer.link b/doc/examples/json_pointer.link new file mode 100644 index 00000000..c10c5fb9 --- /dev/null +++ b/doc/examples/json_pointer.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/json_pointer.output b/doc/examples/json_pointer.output new file mode 100644 index 00000000..b81c8a20 --- /dev/null +++ b/doc/examples/json_pointer.output @@ -0,0 +1,3 @@ +domain_error: JSON pointer must be empty or begin with '/' +domain_error: escape error: '~' must be followed with '0' or '1' +domain_error: escape error: '~' must be followed with '0' or '1' diff --git a/src/json.hpp b/src/json.hpp index 6cf369bd..c40e004a 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -8913,11 +8913,26 @@ basic_json_parser_63: friend class basic_json; public: - /// empty reference token - json_pointer() = default; + /*! + @brief create JSON pointer - /// nonempty reference token - explicit json_pointer(const std::string& s) + Create a JSON pointer according to the syntax described in + [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3). + + @param[in] s string representing the JSON pointer; if omitted, the + empty string is assumed which references the whole JSON + value + + @throw std::domain_error if reference token is nonempty and does not + begin with a slash (`/`), or if a tilde (`~`) is not followed + by `0` (representing `~`) or `1` (representing `/`). + + @liveexample{The example shows the construction several valid JSON + pointers as well as the exceptional behavior.,json_pointer} + + @since version 2.0.0 + */ + explicit json_pointer(const std::string& s = "") : reference_tokens(split(s)) {} @@ -8943,19 +8958,19 @@ basic_json_parser_63: { result = &result->operator[](reference_token); } - continue; + break; } case value_t::object: { result = &result->operator[](reference_token); - continue; + break; } case value_t::array: { result = &result->operator[](static_cast(std::stoi(reference_token))); - continue; + break; } default: @@ -9066,7 +9081,7 @@ basic_json_parser_63: case value_t::object: { ptr = &ptr->operator[](reference_token); - continue; + break; } case value_t::array: @@ -9078,7 +9093,7 @@ basic_json_parser_63: ") is out of range"); } ptr = &ptr->operator[](static_cast(std::stoi(reference_token))); - continue; + break; } default: @@ -9100,7 +9115,7 @@ basic_json_parser_63: case value_t::object: { ptr = &ptr->at(reference_token); - continue; + break; } case value_t::array: @@ -9112,7 +9127,7 @@ basic_json_parser_63: ") is out of range"); } ptr = &ptr->at(static_cast(std::stoi(reference_token))); - continue; + break; } default: diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 7fe9673f..e2ea78b6 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -8223,11 +8223,26 @@ class basic_json friend class basic_json; public: - /// empty reference token - json_pointer() = default; + /*! + @brief create JSON pointer - /// nonempty reference token - explicit json_pointer(const std::string& s) + Create a JSON pointer according to the syntax described in + [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3). + + @param[in] s string representing the JSON pointer; if omitted, the + empty string is assumed which references the whole JSON + value + + @throw std::domain_error if reference token is nonempty and does not + begin with a slash (`/`), or if a tilde (`~`) is not followed + by `0` (representing `~`) or `1` (representing `/`). + + @liveexample{The example shows the construction several valid JSON + pointers as well as the exceptional behavior.,json_pointer} + + @since version 2.0.0 + */ + explicit json_pointer(const std::string& s = "") : reference_tokens(split(s)) {} @@ -8253,19 +8268,19 @@ class basic_json { result = &result->operator[](reference_token); } - continue; + break; } case value_t::object: { result = &result->operator[](reference_token); - continue; + break; } case value_t::array: { result = &result->operator[](static_cast(std::stoi(reference_token))); - continue; + break; } default: @@ -8376,7 +8391,7 @@ class basic_json case value_t::object: { ptr = &ptr->operator[](reference_token); - continue; + break; } case value_t::array: @@ -8388,7 +8403,7 @@ class basic_json ") is out of range"); } ptr = &ptr->operator[](static_cast(std::stoi(reference_token))); - continue; + break; } default: @@ -8410,7 +8425,7 @@ class basic_json case value_t::object: { ptr = &ptr->at(reference_token); - continue; + break; } case value_t::array: @@ -8422,7 +8437,7 @@ class basic_json ") is out of range"); } ptr = &ptr->at(static_cast(std::stoi(reference_token))); - continue; + break; } default: