Skip to content

Commit

Permalink
json_location erase
Browse files Browse the repository at this point in the history
  • Loading branch information
danielaparker committed Nov 16, 2023
1 parent 826abdd commit 7033ee4
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 9 deletions.
48 changes: 43 additions & 5 deletions include/jsoncons_ext/jsonpath/json_location.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,24 +222,62 @@ namespace jsonpath {
}
};


template<class Json>
std::size_t remove(Json& instance, const basic_json_location<typename Json::char_type>& location)
std::size_t erase(Json& instance, const basic_json_location<typename Json::char_type>& location)
{
std::size_t count = 0;

Json* p_current = std::addressof(instance);
for (const auto& element : location)

std::size_t last = location.size() == 0 ? 0 : location.size() - 1;
for (std::size_t i = 0; i < location.size(); ++i)
{
const auto& element = location[i];
if (element.has_name())
{
if (p_current->is_object())
{

auto it = p_current->find(element.name());
if (it != p_current->object_range().end())
{
if (i < last)
{
p_current = std::addressof(it->value());
}
else
{
p_current->erase(it);
count = 1;
}
}
else
{
break;
}
}
else
{
break;
}
}
else
else // if (element.has_index())
{
if (p_current->is_array() && element.index() < p_current->size())
{
if (i < last)
{
p_current = std::addressof(p_current->at(element.index()));
}
else
{
p_current->erase(p_current->array_range().begin()+element.index());
count = 1;
}
}
else
{
break;
}
}
}
return count;
Expand Down
136 changes: 132 additions & 4 deletions test/jsonpath/src/json_location_tests.cpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
// Copyright 2013-2023 Daniel Parker
// Distributed under Boost license

#include <jsoncons_ext/jsonpath/json_location.hpp>
#include <jsoncons_ext/jsonpath/jsonpath.hpp>
#include <catch/catch.hpp>
#include <iostream>

using namespace jsoncons;

TEST_CASE("test json_location")
TEST_CASE("json_location tests")
{

SECTION("test 1")
{
jsonpath::json_location loc;
loc /= "foo";
loc /= 1;
loc.append("foo").append(1);

CHECK(loc.size() == 2);
CHECK(loc[0].has_name());
Expand All @@ -23,3 +23,131 @@ TEST_CASE("test json_location")
}
}


TEST_CASE("json_location erase tests")
{

std::string json_string = R"(
{ "store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
}
]
}
}
)";

json doc = json::parse(json_string);

SECTION("store book 1")
{
jsonpath::json_location loc;
loc.append("store").append("book").append(1);


CHECK(doc["store"]["book"].size() == 3);
CHECK(doc["store"]["book"][1]["author"].as<std::string>() == "Evelyn Waugh");

std::size_t count = jsonpath::erase(doc, loc);

CHECK(count == 1);
CHECK(doc["store"]["book"].size() == 2);
CHECK(doc["store"]["book"][1]["author"].as<std::string>() == "Herman Melville");
}

SECTION("store book 2")
{
jsonpath::json_location loc;
loc.append("store").append("book").append(2);


CHECK(doc["store"]["book"].size() == 3);
CHECK(doc["store"]["book"][2]["author"].as<std::string>() == "Herman Melville");

std::size_t count = jsonpath::erase(doc, loc);

CHECK(count == 1);
CHECK(doc["store"]["book"].size() == 2);
CHECK(doc["store"]["book"][1]["author"].as<std::string>() == "Evelyn Waugh");
}

SECTION("store book 3")
{
jsonpath::json_location loc;
loc.append("store").append("book").append(3);

CHECK(doc["store"]["book"].size() == 3);
CHECK(doc["store"]["book"][2]["author"].as<std::string>() == "Herman Melville");

std::size_t count = jsonpath::erase(doc, loc);

CHECK(count == 0);
CHECK(doc["store"]["book"].size() == 3);
CHECK(doc["store"]["book"][2]["author"].as<std::string>() == "Herman Melville");
}

SECTION("store")
{
jsonpath::json_location loc;
loc.append("store");

std::size_t count = jsonpath::erase(doc, loc);
CHECK(count == 1);
CHECK(doc.size() == 0);
}

SECTION("store book")
{
jsonpath::json_location loc;
loc.append("store").append("book");

CHECK(doc["store"]["book"].size() == 3);
std::size_t count = jsonpath::erase(doc, loc);
CHECK(count == 1);
CHECK(doc["store"]["book"].size() == 0);
}

SECTION("store lost&found")
{
jsonpath::json_location loc;
loc.append("store").append("lost&found");

CHECK(doc["store"].size() == 1);
std::size_t count = jsonpath::erase(doc, loc);
CHECK(count == 0);
CHECK(doc["store"].size() == 1);
}

SECTION("store book 2 price")
{
jsonpath::json_location loc;
loc.append("store").append("book").append(2).append("price");


CHECK(doc["store"]["book"].size() == 3);
CHECK(doc["store"]["book"][2]["author"].as<std::string>() == "Herman Melville");
CHECK(doc["store"]["book"][2].contains("price"));

std::size_t count = jsonpath::erase(doc, loc);

CHECK(count == 1);
CHECK(doc["store"]["book"].size() == 3);
CHECK(doc["store"]["book"][2]["author"].as<std::string>() == "Herman Melville");
CHECK_FALSE(doc["store"]["book"][2].contains("price"));
}
}

0 comments on commit 7033ee4

Please sign in to comment.