Skip to content

Commit

Permalink
Merge pull request #30 from asmello/wip
Browse files Browse the repository at this point in the history
Slice-like Pointers
  • Loading branch information
chanced authored Jun 12, 2024
2 parents 6a5636c + 951fc73 commit 68dbfcb
Show file tree
Hide file tree
Showing 10 changed files with 963 additions and 1,059 deletions.
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

0 comments on commit 68dbfcb

Please sign in to comment.