Skip to content

Commit

Permalink
jsonpointer::assign -> jsonpointer::replace
Browse files Browse the repository at this point in the history
  • Loading branch information
danielaparker committed Sep 19, 2017
1 parent 9f10848 commit 248967b
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 32 deletions.
55 changes: 55 additions & 0 deletions doc/ref/jsonpointer/contains.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
### jsoncons::jsonpointer::contains

Returns `true` if the json doc contains the given json pointer, otherwise `false'

#### Header
```c++
#include <jsoncons_ext/jsonpointer/jsonpointer.hpp>

template<class Json>
bool contains(const Json& doc, typename Json::string_view_type path);

```
#### Return value
Returns `true` if the json doc contains the given json pointer, otherwise `false'
### Examples
#### Examples from [RFC6901](https://tools.ietf.org/html/rfc6901)
```c++
#include <jsoncons/json.hpp>
#include <jsoncons_ext/jsonpointer/jsonpointer.hpp>
using namespace jsoncons;
int main()
{
// Example from RFC 6901
const json example = json::parse(R"(
{
"foo": ["bar", "baz"],
"": 0,
"a/b": 1,
"c%d": 2,
"e^f": 3,
"g|h": 4,
"i\\j": 5,
"k\"l": 6,
" ": 7,
"m~n": 8
}
)");
std::cout << "(1) " << jsonpointer::contains(example, "/foo/0") << std::endl;
std::cout << "(2) " << jsonpointer::contains(example, "e^g") << std::endl;
}
```
Output:
```json
(1) true
(2) false
```

6 changes: 5 additions & 1 deletion doc/ref/jsonpointer/jsonpointer.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
The jsonpointer extension implements the IETF standard [JavaScript Object Notation (JSON) Pointer](https://tools.ietf.org/html/rfc6901)

<table border="0">
<tr>
<td><a href="contains.md">get</a></td>
<td>Returns `true` if the json document contains the given json pointer</td>
</tr>
<tr>
<td><a href="get.md">get</a></td>
<td>Get a value from a JSON document using Json Pointer path notation.</td>
Expand All @@ -20,7 +24,7 @@ The jsonpointer extension implements the IETF standard [JavaScript Object Notati
<td>Removes a value from a JSON document using Json Pointer path notation.</td>
</tr>
<tr>
<td><a href="assign.md">assign`</a></td>
<td><a href="replace.md">replace`</a></td>
<td>Replaces a value in a JSON document using Json Pointer path notation.</td>
</tr>
</table>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
### jsoncons::jsonpointer::assign
### jsoncons::jsonpointer::replace

Replace a `json` element or member.

Expand All @@ -7,7 +7,7 @@ Replace a `json` element or member.
#include <jsoncons_ext/jsonpointer/jsonpointer.hpp>

template<class Json>
jsonpointer_errc assign(Json& target, typename Json::string_view_type path, const Json& value);
jsonpointer_errc replace(Json& target, typename Json::string_view_type path, const Json& value);
```
Replaces the value at the location specified by `path` with a new value.
Expand Down Expand Up @@ -37,7 +37,7 @@ int main()
}
)");
auto ec = jsonpointer::assign(target, "/baz", json("boo"));
auto ec = jsonpointer::replace(target, "/baz", json("boo"));
if (ec == jsonpointer::jsonpointer_errc())
{
std::cout << target << std::endl;
Expand Down Expand Up @@ -70,7 +70,7 @@ int main()
{ "foo": [ "bar", "baz" ] }
)");

auto ec = jsonpointer::assign(target, "/foo/1", json("qux"));
auto ec = jsonpointer::replace(target, "/foo/1", json("qux"));
if (ec == jsonpointer::jsonpointer_errc())
{
std::cout << pretty_print(target) << std::endl;
Expand Down
4 changes: 2 additions & 2 deletions examples/src/examples.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,15 +440,15 @@ int main()

validation_example();

jsonpointer_examples();

serialization_examples();

csv_examples();

comment_example();

jsonpatch_examples();

jsonpointer_examples();
}
catch (const std::exception& e)
{
Expand Down
31 changes: 27 additions & 4 deletions examples/src/jsonpointer_examples.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,31 @@ void jsonpointer_select_RFC6901()
std::cout << "(12) " << result << std::endl;
}

void jsonpointer_contains()
{
// Example from RFC 6901
const json example = json::parse(R"(
{
"foo": ["bar", "baz"],
"": 0,
"a/b": 1,
"c%d": 2,
"e^f": 3,
"g|h": 4,
"i\\j": 5,
"k\"l": 6,
" ": 7,
"m~n": 8
}
)");

std::cout << "(1) " << jsonpointer::contains(example, "/foo/0") << std::endl;
std::cout << "(2) " << jsonpointer::contains(example, "e^g") << std::endl;
}

void jsonpointer_select_author()
{
json root = json::parse(R"(
json doc = json::parse(R"(
[
{ "category": "reference",
"author": "Nigel Rees",
Expand All @@ -72,7 +94,7 @@ void jsonpointer_select_author()

json result;
jsonpointer::jsonpointer_errc ec;
std::tie(result,ec) = jsonpointer::get(root, "/1/author");
std::tie(result,ec) = jsonpointer::get(doc, "/1/author");

if (ec == jsonpointer::jsonpointer_errc())
{
Expand Down Expand Up @@ -212,7 +234,7 @@ void jsonpointer_replace_object_value()
}
)");

auto ec = jsonpointer::assign(target, "/baz", json("boo"));
auto ec = jsonpointer::replace(target, "/baz", json("boo"));
if (ec == jsonpointer::jsonpointer_errc())
{
std::cout << target << std::endl;
Expand All @@ -229,7 +251,7 @@ void jsonpointer_replace_array_value()
{ "foo": [ "bar", "baz" ] }
)");

auto ec = jsonpointer::assign(target, "/foo/1", json("qux"));
auto ec = jsonpointer::replace(target, "/foo/1", json("qux"));
if (ec == jsonpointer::jsonpointer_errc())
{
std::cout << pretty_print(target) << std::endl;
Expand All @@ -254,6 +276,7 @@ void jsonpointer_examples()
jsonpointer_remove_array_element();
jsonpointer_replace_object_value();
jsonpointer_replace_array_value();
jsonpointer_contains();
std::cout << std::endl;
}

10 changes: 5 additions & 5 deletions include/jsoncons_ext/jsonpatch/jsonpatch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ namespace detail {
}
else if (it->op == op_type::replace)
{
if (jsonpointer::assign(target,it->path,it->value) != jsonpointer::jsonpointer_errc())
if (jsonpointer::replace(target,it->path,it->value) != jsonpointer::jsonpointer_errc())
{
//std::cout << "replace: " << it->path << std::endl;
break;
Expand Down Expand Up @@ -258,7 +258,7 @@ std::tuple<jsonpatch_errc,typename Json::string_type> patch(Json& target, const
patch_ec = jsonpatch_errc::add_failed;
unwinder.state = detail::state_type::abort;
}
else if (jsonpointer::assign(target,npath,val) != jsonpointer::jsonpointer_errc())
else if (jsonpointer::replace(target,npath,val) != jsonpointer::jsonpointer_errc())
{
patch_ec = jsonpatch_errc::add_failed;
unwinder.state = detail::state_type::abort;
Expand Down Expand Up @@ -318,7 +318,7 @@ std::tuple<jsonpatch_errc,typename Json::string_type> patch(Json& target, const
patch_ec = jsonpatch_errc::invalid_patch;
unwinder.state = detail::state_type::abort;
}
else if (jsonpointer::assign(target,path,operation.at(value_key)) != jsonpointer::jsonpointer_errc())
else if (jsonpointer::replace(target,path,operation.at(value_key)) != jsonpointer::jsonpointer_errc())
{
patch_ec = jsonpatch_errc::replace_failed;
unwinder.state = detail::state_type::abort;
Expand Down Expand Up @@ -367,7 +367,7 @@ std::tuple<jsonpatch_errc,typename Json::string_type> patch(Json& target, const
patch_ec = jsonpatch_errc::copy_failed;
unwinder.state = detail::state_type::abort;
}
else if (jsonpointer::assign(target,npath,val) != jsonpointer::jsonpointer_errc())
else if (jsonpointer::replace(target,npath,val) != jsonpointer::jsonpointer_errc())
{
patch_ec = jsonpatch_errc::copy_failed;
unwinder.state = detail::state_type::abort;
Expand Down Expand Up @@ -422,7 +422,7 @@ std::tuple<jsonpatch_errc,typename Json::string_type> patch(Json& target, const
patch_ec = jsonpatch_errc::copy_failed;
unwinder.state = detail::state_type::abort;
}
else if (jsonpointer::assign(target,npath,val) != jsonpointer::jsonpointer_errc())
else if (jsonpointer::replace(target,npath,val) != jsonpointer::jsonpointer_errc())
{
patch_ec = jsonpatch_errc::copy_failed;
unwinder.state = detail::state_type::abort;
Expand Down
23 changes: 21 additions & 2 deletions include/jsoncons_ext/jsonpointer/jsonpointer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ class jsonpointer_evaluator : private parsing_context
return ec;
}

jsonpointer_errc assign(json_reference root,
jsonpointer_errc replace(json_reference root,
typename Json::string_view_type path,
const Json& value)
{
Expand Down Expand Up @@ -605,6 +605,14 @@ std::tuple<Json,jsonpointer_errc> get(const Json& root, typename Json::string_vi
return std::make_tuple(evaluator.get_result(),ec);
}

template<class Json>
bool contains(const Json& root, typename Json::string_view_type path)
{
detail::jsonpointer_evaluator<Json,const Json&,const Json*> evaluator;
jsonpointer_errc ec = evaluator.get(root,path);
return ec == jsonpointer_errc() ? true : false;
}

template<class Json>
jsonpointer_errc insert_or_assign(Json& root, typename Json::string_view_type path, const Json& value)
{
Expand All @@ -629,13 +637,24 @@ jsonpointer_errc erase(Json& root, typename Json::string_view_type path)
return evaluator.erase(root,path);
}

template<class Json>
jsonpointer_errc replace(Json& root, typename Json::string_view_type path, const Json& value)
{
detail::jsonpointer_evaluator<Json> evaluator;

return evaluator.replace(root,path,value);
}

#if !defined(JSONCONS_NO_DEPRECATED)

template<class Json>
jsonpointer_errc assign(Json& root, typename Json::string_view_type path, const Json& value)
{
detail::jsonpointer_evaluator<Json> evaluator;

return evaluator.assign(root,path,value);
return evaluator.replace(root,path,value);
}
#endif

template <class String>
void escape(const String& s, std::basic_ostringstream<typename String::value_type>& os)
Expand Down
48 changes: 34 additions & 14 deletions tests/src/jsonpointer/jsonpointer_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const json example = json::parse(R"(
}
)");

void check_select(const std::string pointer, const json& expected)
void check_get(const std::string& pointer, const json& expected)
{

json result;
Expand All @@ -50,6 +50,13 @@ void check_select(const std::string pointer, const json& expected)
BOOST_CHECK_EQUAL(expected,result);
}

void check_contains(const std::string& pointer, bool expected)
{

bool result = jsonpointer::contains(example,pointer);
BOOST_CHECK_EQUAL(expected,result);
}

void check_add(json& example, const std::string& path, const json& value, const json& expected)
{
jsonpointer::jsonpointer_errc ec = jsonpointer::insert_or_assign(example, path, value);
Expand All @@ -59,7 +66,7 @@ void check_add(json& example, const std::string& path, const json& value, const

void check_replace(json& example, const std::string& path, const json& value, const json& expected)
{
jsonpointer::jsonpointer_errc ec = jsonpointer::assign(example, path, value);
jsonpointer::jsonpointer_errc ec = jsonpointer::replace(example, path, value);
BOOST_CHECK_EQUAL(ec,jsonpointer::jsonpointer_errc());
BOOST_CHECK_EQUAL(expected, example);
}
Expand All @@ -73,18 +80,31 @@ void check_remove(json& example, const std::string& path, const json& expected)

BOOST_AUTO_TEST_CASE(test_jsonpointer)
{
check_select("",example);
check_select("/foo",json::parse("[\"bar\", \"baz\"]"));
check_select("/foo/0",json("bar"));
check_select("/",json(0));
check_select("/a~1b",json(1));
check_select("/c%d",json(2));
check_select("/e^f",json(3));
check_select("/g|h",json(4));
check_select("/i\\j",json(5));
check_select("/k\"l",json(6));
check_select("/ ",json(7));
check_select("/m~0n",json(8));
check_contains("",true);
check_contains("/foo",true);
check_contains("/foo/0",true);
check_contains("/",true);
check_contains("/a~1b",true);
check_contains("/c%d",true);
check_contains("/e^f",true);
check_contains("/g|h",true);
check_contains("/i\\j",true);
check_contains("/k\"l",true);
check_contains("/ ",true);
check_contains("/m~0n",true);

check_get("",example);
check_get("/foo",json::parse("[\"bar\", \"baz\"]"));
check_get("/foo/0",json("bar"));
check_get("/",json(0));
check_get("/a~1b",json(1));
check_get("/c%d",json(2));
check_get("/e^f",json(3));
check_get("/g|h",json(4));
check_get("/i\\j",json(5));
check_get("/k\"l",json(6));
check_get("/ ",json(7));
check_get("/m~0n",json(8));
}

// add
Expand Down

0 comments on commit 248967b

Please sign in to comment.