Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slice-like Pointers #30

Merged
merged 14 commits into from
Jun 12, 2024
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ url = { version = "2", optional = true }
[features]
default = ["std"]
std = ["serde/std", "serde_json/std", "fluent-uri?/std"]

[dev-dependencies]
quickcheck = "1.0.3"
quickcheck_macros = "1.0.0"
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use jsonptr::Pointer;
use serde_json::json;

let mut data = json!({"foo": { "bar": "baz" }});
let ptr = Pointer::new(["foo", "bar"]);
let ptr = Pointer::from_static("/foo/bar");
let bar = ptr.resolve(&data).unwrap();
assert_eq!(bar, "baz");
```
Expand All @@ -33,7 +33,7 @@ use jsonptr::{Pointer, Resolve};
use serde_json::json;

let mut data = json!({ "foo": { "bar": "baz" }});
let ptr = Pointer::new(["foo", "bar"]);
let ptr = Pointer::from_static("/foo/bar");
let bar = data.resolve(&ptr).unwrap();
assert_eq!(bar, "baz");

Expand All @@ -45,7 +45,7 @@ assert_eq!(bar, "baz");
use jsonptr::{Pointer, ResolveMut};
use serde_json::json;

let ptr = Pointer::try_from("/foo/bar").unwrap();
let ptr = Pointer::from_static("/foo/bar");
let mut data = json!({ "foo": { "bar": "baz" }});
let mut bar = data.resolve_mut(&ptr).unwrap();
assert_eq!(bar, "baz");
Expand All @@ -59,7 +59,7 @@ assert_eq!(bar, "baz");
use jsonptr::Pointer;
use serde_json::json;

let ptr = Pointer::try_from("/foo/bar").unwrap();
let ptr = Pointer::from_static("/foo/bar");
let mut data = json!({});
let _previous = ptr.assign(&mut data, "qux").unwrap();
assert_eq!(data, json!({ "foo": { "bar": "qux" }}))
Expand All @@ -71,7 +71,7 @@ assert_eq!(data, json!({ "foo": { "bar": "qux" }}))
use jsonptr::{Assign, Pointer};
use serde_json::json;

let ptr = Pointer::try_from("/foo/bar").unwrap();
let ptr = Pointer::from_static("/foo/bar");
let mut data = json!({});
let _previous = data.assign(&ptr, "qux").unwrap();
assert_eq!(data, json!({ "foo": { "bar": "qux" }}))
Expand All @@ -86,7 +86,7 @@ use jsonptr::Pointer;
use serde_json::json;

let mut data = json!({ "foo": { "bar": { "baz": "qux" } } });
let ptr = Pointer::new(&["foo", "bar", "baz"]);
let ptr = Pointer::from_static("/foo/bar/baz");
assert_eq!(ptr.delete(&mut data), Some("qux".into()));
assert_eq!(data, json!({ "foo": { "bar": {} } }));

Expand All @@ -102,12 +102,12 @@ use jsonptr::{Pointer, Delete};
use serde_json::json;

let mut data = json!({ "foo": { "bar": { "baz": "qux" } } });
let ptr = Pointer::new(["foo", "bar", "baz"]);
let ptr = Pointer::from_static("/foo/bar/baz");
assert_eq!(ptr.delete(&mut data), Some("qux".into()));
assert_eq!(data, json!({ "foo": { "bar": {} } }));

// replacing a root pointer replaces data with `Value::Null`
let ptr = Pointer::default();
let ptr = Pointer::root();
let deleted = json!({ "foo": { "bar": {} } });
assert_eq!(data.delete(&ptr), Some(deleted));
assert!(data.is_null());
Expand Down
36 changes: 36 additions & 0 deletions src/arbitrary.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use crate::{PointerBuf, Token};
use alloc::{
boxed::Box,
string::{String, ToString},
vec::Vec,
};
use quickcheck::Arbitrary;

impl Arbitrary for Token {
fn arbitrary(g: &mut quickcheck::Gen) -> Self {
Self::new(String::arbitrary(g))
}

fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
Box::new(ToString::to_string(self).shrink().map(Self::new))
}
}

impl Arbitrary for PointerBuf {
fn arbitrary(g: &mut quickcheck::Gen) -> Self {
let size = usize::arbitrary(g) % g.size();
Self::from_tokens((0..size).map(|_| Token::arbitrary(g)).collect::<Vec<_>>())
}

fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
let tokens: Vec<_> = self.tokens().collect();
Box::new((0..self.count()).map(move |i| {
let subset: Vec<_> = tokens
.iter()
.enumerate()
.filter_map(|(j, t)| (i != j).then_some(t.clone()))
.collect();
Self::from_tokens(subset)
}))
}
}
11 changes: 6 additions & 5 deletions src/assign.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use alloc::borrow::Cow;
use serde_json::Value;

use crate::{Error, Pointer};
use crate::{Error, Pointer, PointerBuf};

/// Assign is implemented by types which can internally assign a
/// `serde_json::Value` by a JSON Pointer.
Expand All @@ -23,6 +23,7 @@ impl Assign for Value {
ptr.assign(self, value)
}
}

#[derive(Debug)]
/// The data structure returned from a successful call to `assign`.
pub struct Assignment<'a> {
Expand Down Expand Up @@ -65,17 +66,17 @@ pub struct Assignment<'a> {
/// ```
/// and you assigned `"new_value"` to `"/foo/bar/baz"`, then the value would
/// be `Some("/foo/bar")`.
pub created_or_mutated: Pointer,
pub created_or_mutated: PointerBuf,
/// A `Pointer` consisting of the path which was assigned.
///
/// ## Example
/// ```rust
/// use serde_json::json;
/// use jsonptr::{Pointer, Assign};
/// let mut data = json!({ "foo": ["zero"] });
/// let mut ptr = Pointer::try_from("/foo/-").unwrap();
/// let mut ptr = Pointer::from_static("/foo/-");
/// let assignment = data.assign(&mut ptr, "one").unwrap();
/// assert_eq!(assignment.assigned_to, Pointer::try_from("/foo/1").unwrap());
/// assert_eq!(assignment.assigned_to, Pointer::from_static("/foo/1"));
/// ```
pub assigned_to: Pointer,
pub assigned_to: PointerBuf,
}
16 changes: 6 additions & 10 deletions src/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,16 @@ impl Delete for Value {

#[cfg(test)]
mod tests {
use serde_json::json;

use super::*;
use serde_json::json;

#[test]
fn test_issue_18() {
let mut data = json!(
{
"Example": 21,
"test": "test"
}
);
let pointer = Pointer::new(["Example"]);
println!("{}", pointer);
let mut data = json!({
"Example": 21,
"test": "test"
});
let pointer = Pointer::from_static("/Example");
pointer.delete(&mut data);
assert_eq!(json!({"test": "test"}), data);
}
Expand Down
16 changes: 8 additions & 8 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use alloc::{
vec::Vec,
};

use crate::{Pointer, Token};
use crate::{PointerBuf, Token};
use core::{
// error::Error as StdError,
fmt::{Debug, Display, Formatter},
Expand Down Expand Up @@ -97,14 +97,14 @@ impl std::error::Error for Error {}
/// use serde_json::json;
/// use jsonptr::{Pointer, ResolveMut, Resolve, UnresolvableError};
/// let mut data = json!({ "foo": "bar" });
/// let ptr = Pointer::try_from("/foo/unreachable").unwrap();
/// let ptr = Pointer::from_static("/foo/unreachable");
/// let err = data.resolve_mut(&ptr).unwrap_err();
/// assert_eq!(err, UnresolvableError::new(ptr.clone()).into());
/// assert_eq!(err, UnresolvableError::new(ptr.to_buf()).into());
/// ```
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct UnresolvableError {
/// The unresolved `Pointer`.
pub pointer: Pointer,
pub pointer: PointerBuf,
/// The leaf node, if applicable, which was expected to be either an
/// `Object` or an `Array`.
pub leaf: Option<Token>,
Expand All @@ -115,7 +115,7 @@ impl std::error::Error for UnresolvableError {}

impl UnresolvableError {
/// Creates a new `UnresolvableError` with the given `Pointer`.
pub fn new(pointer: Pointer) -> Self {
pub fn new(pointer: PointerBuf) -> Self {
let leaf = if pointer.count() >= 2 {
Some(pointer.get(pointer.count() - 2).unwrap())
} else {
Expand Down Expand Up @@ -288,11 +288,11 @@ impl std::error::Error for MalformedPointerError {}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct NotFoundError {
/// The `Pointer` which could not be resolved.
pub pointer: Pointer,
pub pointer: PointerBuf,
}
impl NotFoundError {
/// Creates a new `NotFoundError` with the given `Pointer`.
pub fn new(pointer: Pointer) -> Self {
pub fn new(pointer: PointerBuf) -> Self {
NotFoundError { pointer }
}
}
Expand All @@ -317,7 +317,7 @@ pub struct ReplaceTokenError {
/// The number of tokens in the `Pointer`.
pub count: usize,
/// The subject `Pointer`.
pub pointer: Pointer,
pub pointer: PointerBuf,
}
#[cfg(feature = "std")]
impl std::error::Error for ReplaceTokenError {}
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ pub mod prelude;

mod tokens;
pub use tokens::*;

#[cfg(test)]
mod arbitrary;
Loading
Loading