#json-path #json-parser #serde-json #json-pointer #rfc-6901 #6901

no-std jsonptr

Data structures and logic for resolving, assigning, and deleting by JSON Pointers (RFC 6901)

32 releases

0.6.3 Oct 1, 2024
0.6.0 Aug 10, 2024
0.5.1 Jul 10, 2024
0.4.7 Mar 18, 2024
0.1.5 Jun 30, 2022

#72 in Parser implementations

Download history 138415/week @ 2024-08-22 136498/week @ 2024-08-29 164934/week @ 2024-09-05 163561/week @ 2024-09-12 169367/week @ 2024-09-19 175642/week @ 2024-09-26 212303/week @ 2024-10-03 202133/week @ 2024-10-10 216952/week @ 2024-10-17 255778/week @ 2024-10-24 225391/week @ 2024-10-31 244698/week @ 2024-11-07 222535/week @ 2024-11-14 187188/week @ 2024-11-21 132732/week @ 2024-11-28 160395/week @ 2024-12-05

746,619 downloads per month
Used in 254 crates (9 directly)

MIT/Apache

215KB
3.5K SLoC

jsonptr - JSON Pointers (RFC 6901) for Rust

github crates.io docs.rs build status code coverage

JSON Pointers (RFC 6901) defines a string syntax for identifying a specific location within a JSON, or similar, document. This crate provides two types, Pointer and PointerBuf (akin to Path and PathBuf), for working with them abstractly.

A pointer is composed of zero or more Tokens, single segments which represent a field of an object or an index of an array, and are bounded by either '/' or the end of the string. Tokens are lightly encoded, where '~' is escaped as "~0" due to it signaling encoding and '/' is escaped as "~1" because '/' separates tokens and would split the token into two otherwise.

Tokens can be iterated over using either Tokens, returned from the tokens method of a pointer or Components, returned from the components method. The difference being that Tokens iterates over each token in the pointer, while Components iterates over Components, which can represent the root of the document or a single token of the pointer.

Operations resolve, assign and delete are provided as traits with corresponding methods on pointer types. Implementations of each trait are provided for value types of the crates serde_json and toml. All operations are enabled by default but are gated by feature flags.

Usage

To parse a Pointer from a string, use either Pointer::parse, for potentially fallible parsing, or the const fn from_static to produce a &'static Pointer from a string that is known to be valid.

use jsonptr::Pointer;

let ptr = Pointer::parse("/examples/0/name").unwrap();
let static_ptr = Pointer::from_static("/examples/0/name");
assert_eq!(ptr, static_ptr);

let parent = ptr.parent().unwrap();
assert_eq!(parent, Pointer::parse("/examples/0").unwrap());

let (token, remaining) = ptr.split_front().unwrap();
assert_eq!(token.decoded(), "examples");
assert_eq!(remaining, Pointer::parse("/0/name").unwrap());

PointerBufs can be parsed using PointerBuf::parse or constructed from an iterator of Tokens with the from_tokens method:

use jsonptr::PointerBuf;
let mut buf = PointerBuf::parse("/examples/0/name").unwrap();

let from_tokens = PointerBuf::from_tokens(["examples", "0", "name"]);
assert_eq!(&buf, &from_tokens);

buf.push_front("pointer");
buf.push_front("~");
buf.push_back("/");
assert_eq!(buf.as_str(), "/~0/pointer/examples/0/name/~1");

Iterating over the tokens or components of a pointer:

use jsonptr::{Pointer, Component, Token};
let ptr = Pointer::from_static("/path/to/value");

//  Using the `tokens` method:
let tokens: Vec<_> = ptr.tokens().collect();
assert_eq!(tokens, vec![Token::new("path"), Token::new("to"), Token::new("value")]);

// Using the `components` method:
let mut components = ptr.components();
assert_eq!(components.next(), Some(Component::Root));
assert_eq!(components.next(), Some(Component::Token(Token::new("path"))));
assert_eq!(components.next(), Some(Component::Token(Token::new("to"))));
assert_eq!(components.next(), Some(Component::Token(Token::new("value"))));

To get a value at the location of a pointer, use either the Resolve and ResolveMut traits or Pointer::resolve and Pointer::resolve_mut methods. See the resolve mod for more information.

use jsonptr::Pointer;
use serde_json::json;

let ptr = Pointer::parse("/foo/bar").unwrap();
let data = json!({"foo": { "bar": 34 }});
let bar = ptr.resolve(&data).unwrap();
assert_eq!(bar, &json!(34));

Values can be set, with path expansion, using the either the Assign trait or Pointer::assign. See assign for more information.

use jsonptr::Pointer;
use serde_json::json;

let ptr = Pointer::parse("/secret/universe").unwrap();
let mut data = json!({"secret": { "universe": 42 }});
let replaced = ptr.assign(&mut data, json!(34)).unwrap();
assert_eq!(replaced, Some(json!(42)));
assert_eq!(data, json!({"secret": { "universe": 34 }}));

Values can be removed with the either the Delete trait or Pointer::delete. See delete for more information.

use jsonptr::Pointer;
use serde_json::json;

let ptr = Pointer::parse("/secret/universe").unwrap();
let mut data = json!({"secret": { "universe": 42 }});
let replaced = ptr.assign(&mut data, json!(34)).unwrap();
assert_eq!(replaced, Some(json!(42)));
assert_eq!(data, json!({"secret": { "universe": 34 }}));

Feature Flags

Flag Description Enables Default
"std" Implements std::error::Error for error types
"serde" Enables serde support for types
"json" Implements ops for serde_json::Value "serde"
"toml" Implements ops for toml::Value "std", toml
"assign" Enables the assign module and related pointer methods, providing a means to assign a value to a specific location within a document
"resolve" Enables the resolve module and related pointer methods, providing a means to resolve a value at a specific location within a document
"delete" Enables the delete module and related pointer methods, providing a means to delete a value at a specific location within a document "resolve"

License

Licensed under either of

at your convenience.

Contribution

Contributions and feedback are always welcome and appreciated. If you find an issue, please open a ticket or a pull request.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Dependencies

~100–550KB
~12K SLoC