MCPcopy Index your code
hub / github.com/chanced/jsonptr

github.com/chanced/jsonptr @v0.7.1

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.7.1 ↗ · + Follow
281 symbols 622 edges 11 files 81 documented · 29%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

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 [Token]s, 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.

[Token]s 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 [Component]s, 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

Parsing and General 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);

assert_eq!(ptr.get(1..).unwrap(), Pointer::parse("/0/name").unwrap());

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());

[PointerBuf]s can be parsed using [PointerBuf::parse] or constructed from an iterator of [Token]s 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");

Token Iteration

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"))));

Resolving Values

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));

Assigning Values

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 }}));

Deleting Values

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 }}));

Error Reporting

Any error produced by function calls into methods of traits or types of this crate can be converted into a [Report] which contains the original error and the [String] which failed to parse or the [PointerBuf] which failed to resolve or assign.

    use jsonptr::{Pointer, Diagnose};
    let ptr_str = "foo/bar";
    let err /* Result<&Pointer, Report<ParseError>> */ = Pointer::parse(ptr_str).diagnose(ptr_str).unwrap_err();
    assert!(err.original().is_no_leading_slash());

In the case of [PointerBuf::parse], the [ParseError] is always wrapped in a [Report] so that the input String is not dropped.

    use jsonptr::{PointerBuf};
    let ptr_str = "foo/bar";
    let err /* Result<&PointerBuf, Report<ParseError>> */ = PointerBuf::parse(ptr_str).unwrap_err();
    assert!(err.original().is_no_leading_slash());

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"
"miette" Enables integration with miette for error reporting "std"

License

Licensed under either of

  • Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
  • MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)

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.

Extension points exported contracts — how you extend this code

Diagnostic (Interface)
Implemented by errors which can be converted into a [`Report`]. [6 implementers]
src/diagnostic.rs
PointerIndex (Interface)
(no doc) [8 implementers]
src/pointer/slice.rs
Assign (Interface)
Implemented by types which can internally assign a ([`Value`](`Assign::Value`)) at a path represented by a JSON [`Pointe [2 …
src/assign.rs
Resolve (Interface)
A trait implemented by types which can resolve a reference to a value type from a path represented by a JSON [`Pointer`] [2 …
src/resolve.rs
Delete (Interface)
Delete is implemented by types which can internally remove a value based on a JSON Pointer [2 implementers]
src/delete.rs
Diagnose (Interface)
An extension trait for `Result<_, E>`, where `E` is an implementation of [`Diagnostic`], that converts `E` into [`Report [1 …
src/diagnostic.rs
Sealed (Interface)
(no doc) [8 implementers]
src/pointer/slice.rs
ResolveMut (Interface)
A trait implemented by types which can resolve a mutable reference to a value type from a path represented by a JSON [`P [2 …
src/resolve.rs

Core symbols most depended-on inside this repo

get
called by 96
src/pointer/slice.rs
len
called by 37
src/pointer.rs
get
called by 28
src/pointer.rs
encoded
called by 23
src/token.rs
is_root
called by 19
src/pointer.rs
as_str
called by 16
src/pointer.rs
tokens
called by 16
src/pointer.rs
push_back
called by 14
src/pointer.rs

Shape

Method 142
Function 106
Class 17
Enum 8
Interface 8

Languages

Rust100%

Modules by API surface

src/pointer.rs135 symbols
src/index.rs28 symbols
src/token.rs25 symbols
src/resolve.rs25 symbols
src/diagnostic.rs22 symbols
src/assign.rs21 symbols
src/pointer/slice.rs11 symbols
src/delete.rs7 symbols
src/component.rs5 symbols
src/arbitrary.rs2 symbols

For agents

$ claude mcp add jsonptr \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact