mirror of
https://github.com/boostorg/json.git
synced 2026-01-19 04:12:14 +00:00
try_at_pointer and try_set_at_pointer
This commit is contained in:
@@ -341,13 +341,23 @@ walk_pointer(
|
||||
|
||||
} // namespace detail
|
||||
|
||||
value const&
|
||||
value::at_pointer(string_view ptr) const&
|
||||
system::result<value const&>
|
||||
value::try_at_pointer(string_view ptr) const noexcept
|
||||
{
|
||||
system::error_code ec;
|
||||
auto const found = find_pointer(ptr, ec);
|
||||
if( !found )
|
||||
detail::throw_system_error( ec );
|
||||
return ec;
|
||||
return *found;
|
||||
}
|
||||
|
||||
system::result<value&>
|
||||
value::try_at_pointer(string_view ptr) noexcept
|
||||
{
|
||||
system::error_code ec;
|
||||
auto const found = find_pointer(ptr, ec);
|
||||
if( !found )
|
||||
return ec;
|
||||
return *found;
|
||||
}
|
||||
|
||||
@@ -484,15 +494,24 @@ value::set_at_pointer(
|
||||
return result;
|
||||
}
|
||||
|
||||
system::result<value&>
|
||||
value::try_set_at_pointer(
|
||||
string_view sv,
|
||||
value_ref ref,
|
||||
set_pointer_options const& opts )
|
||||
{
|
||||
system::error_code ec;
|
||||
value* result = set_at_pointer( sv, ref, ec, opts );
|
||||
if( result )
|
||||
return *result;
|
||||
return ec;
|
||||
}
|
||||
|
||||
value&
|
||||
value::set_at_pointer(
|
||||
string_view sv, value_ref ref, set_pointer_options const& opts )
|
||||
{
|
||||
system::error_code ec;
|
||||
value* result = set_at_pointer( sv, ref, ec, opts );
|
||||
if( !result )
|
||||
detail::throw_system_error( ec );
|
||||
return *result;
|
||||
return try_set_at_pointer(sv, ref, opts).value();
|
||||
}
|
||||
|
||||
} // namespace json
|
||||
|
||||
@@ -13,17 +13,22 @@
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
value const&
|
||||
value::at_pointer(string_view ptr) const&
|
||||
{
|
||||
return try_at_pointer(ptr).value();
|
||||
}
|
||||
|
||||
value&
|
||||
value::at_pointer(string_view ptr) &
|
||||
{
|
||||
auto const& self = *this;
|
||||
return const_cast<value&>( self.at_pointer(ptr) );
|
||||
return try_at_pointer(ptr).value();
|
||||
}
|
||||
|
||||
value&&
|
||||
value::at_pointer(string_view ptr) &&
|
||||
{
|
||||
return std::move( this->at_pointer(ptr) );
|
||||
return std::move( try_at_pointer(ptr).value() );
|
||||
}
|
||||
|
||||
} // namespace json
|
||||
|
||||
@@ -3284,6 +3284,53 @@ public:
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** Access an element via JSON Pointer.
|
||||
|
||||
This function is used to access a (potentially nested) element of the
|
||||
value using a JSON Pointer string.
|
||||
|
||||
@par Complexity
|
||||
Linear in the sizes of `ptr` and underlying array, object, or string.
|
||||
|
||||
@par Exception Safety
|
||||
No-throw guarantee.
|
||||
|
||||
@param ptr JSON Pointer string.
|
||||
|
||||
@return `boost::system::result<value&>` containing either a reference
|
||||
to the element identified by `ptr` or a corresponding `error_code`.
|
||||
|
||||
@see
|
||||
[RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
system::result<value const&>
|
||||
try_at_pointer(string_view ptr) const noexcept;
|
||||
|
||||
/** Access an element via JSON Pointer.
|
||||
|
||||
This function is used to access a (potentially nested) element of the
|
||||
value using a JSON Pointer string.
|
||||
|
||||
@par Complexity
|
||||
Linear in the sizes of `ptr` and underlying array, object, or string.
|
||||
|
||||
@par Exception Safety
|
||||
No-throw guarantee.
|
||||
|
||||
@param ptr JSON Pointer string.
|
||||
|
||||
@return `boost::system::result<value const&>` containing either a
|
||||
reference to the element identified by `ptr` or a corresponding
|
||||
`error_code`.
|
||||
|
||||
@see
|
||||
[RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
system::result<value&>
|
||||
try_at_pointer(string_view ptr) noexcept;
|
||||
|
||||
/** Access an element via JSON Pointer.
|
||||
|
||||
This function is used to access a (potentially nested)
|
||||
@@ -3306,7 +3353,7 @@ public:
|
||||
RFC 6901 - JavaScript Object Notation (JSON) Pointer</a>
|
||||
*/
|
||||
/** @{ */
|
||||
BOOST_JSON_DECL
|
||||
inline
|
||||
value const&
|
||||
at_pointer(string_view ptr) const&;
|
||||
|
||||
@@ -3360,6 +3407,72 @@ public:
|
||||
|
||||
//------------------------------------------------------
|
||||
|
||||
/** Set an element via JSON Pointer.
|
||||
|
||||
This function is used to insert or assign to a potentially nested
|
||||
element of the value using a JSON Pointer string. The function may
|
||||
create intermediate elements corresponding to pointer segments.
|
||||
<br/>
|
||||
|
||||
The particular conditions when and what kind of intermediate element
|
||||
is created is governed by the `ptr` parameter.
|
||||
|
||||
Each pointer token is considered in sequence. For each token
|
||||
|
||||
- if the containing value is an @ref object, then a new `null`
|
||||
element is created with key equal to unescaped token string;
|
||||
otherwise
|
||||
|
||||
- if the containing value is an @ref array, and the token represents a
|
||||
past-the-end marker, then a `null` element is appended to the array;
|
||||
otherwise
|
||||
|
||||
- if the containing value is an @ref array, and the token represents a
|
||||
number, then if the difference between the number and array's size
|
||||
is smaller than `opts.max_created_elements`, then the size of the
|
||||
array is increased, so that the number can reference an element in the
|
||||
array; otherwise
|
||||
|
||||
- if the containing value is of different @ref kind and
|
||||
`opts.replace_any_scalar` is `true`, or the value is `null`, then
|
||||
|
||||
- if `opts.create_arrays` is `true` and the token either represents
|
||||
past-the-end marker or a number, then the value is replaced with
|
||||
an empty array and the token is considered again; otherwise
|
||||
|
||||
- if `opts.create_objects` is `true`, then the value is replaced
|
||||
with an empty object and the token is considered again; otherwise
|
||||
|
||||
- an error is produced.
|
||||
|
||||
@par Complexity
|
||||
Linear in the sum of size of `ptr`, size of underlying array, object,
|
||||
or string and `opts.max_created_elements`.
|
||||
|
||||
@par Exception Safety
|
||||
Basic guarantee.
|
||||
Calls to `memory_resource::allocate` may throw.
|
||||
|
||||
@param sv JSON Pointer string.
|
||||
|
||||
@param ref The value to assign to pointed element.
|
||||
|
||||
@param opts The options for the algorithm.
|
||||
|
||||
@return `boost::json::result<value&>` containing either a reference to
|
||||
the element identified by `ptr` or a corresponding `error_code`.
|
||||
|
||||
@see
|
||||
@ref set_pointer_options,
|
||||
[RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
system::result<value&>
|
||||
try_set_at_pointer(
|
||||
string_view sv,
|
||||
value_ref ref,
|
||||
set_pointer_options const& opts = {} );
|
||||
|
||||
/** Set an element via JSON Pointer.
|
||||
|
||||
This function is used to insert or assign to a potentially nested
|
||||
|
||||
@@ -346,6 +346,22 @@ public:
|
||||
BOOST_TEST( hasLocation(ec) );
|
||||
}
|
||||
|
||||
void
|
||||
testTry()
|
||||
{
|
||||
value jv = testValue();
|
||||
BOOST_TEST( &jv.try_at_pointer("/foo").value() == &jv.at("foo") );
|
||||
BOOST_TEST_THROWS_WITH_LOCATION( jv.try_at_pointer("foo").value() );
|
||||
|
||||
value const& cjv = jv;
|
||||
BOOST_TEST( &cjv.try_at_pointer("/foo").value() == &cjv.at("foo") );
|
||||
BOOST_TEST_THROWS_WITH_LOCATION( cjv.try_at_pointer("foo").value() );
|
||||
|
||||
auto result = jv.try_set_at_pointer("", array());
|
||||
BOOST_TEST(( jv == array() ));
|
||||
BOOST_TEST( &*result == &jv );
|
||||
}
|
||||
|
||||
void
|
||||
run()
|
||||
{
|
||||
@@ -359,6 +375,7 @@ public:
|
||||
testSet();
|
||||
testSetNonThrowing<system::error_code>();
|
||||
testSetNonThrowing<std::error_code>();
|
||||
testTry();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user