Skip to content

Commit

Permalink
Merge pull request #13 from chanced/remove-error-from-pointer
Browse files Browse the repository at this point in the history
Remove `MalformedPointer` from `Pointer`
  • Loading branch information
chanced authored May 31, 2023
2 parents 45fbe20 + cc12ecd commit c1961df
Show file tree
Hide file tree
Showing 7 changed files with 268 additions and 116 deletions.
58 changes: 58 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.4.0] 2023-05-31

### Added

- Adds `CHANGELOG.md` which will be better upkept moving forward.
- Adds `MaybePointer` to assist with deserialization which should not fail fast.

### Changed

- `Pointer::new` now accepts a generic list, so `&["example"]` can be replaced by `["example"]`. For untyped, empty slices (i.e. `Pointer::new(&[])`), use `Pointer::default()`.
- `std` is now enabled by default.

### Removed

- Removes optional `MalformedPointerError` from `Pointer`.

## [0.3.6] 2023-05-23

### Changed

- Adds quotes around `Pointer` debug output (#11)

### Fixed

- Adds missing `impl std::error::Error` for `Error`, `NotFoundError`, `MalformedError`
- Fixes build for `std` feature flag

## [0.3.4] 2023-05-11

### Added

- Adds feature flag `fluent-uri` for `From<fluent_uri::Uri<_>` impl (#3)

## [0.2.0] 2023-02-24

### Changed

- `std` is now optional
- Adds feature flags `"uniresid"`, `"url"` to enable implementing `From<Uri>`, `From<Url>` (respectively).

### Removed

- Removes `Cargo.lock`
- Makes `uniresid` and `uri` optional

## [0.1.0] - 2022-06-12

### Fixed

- Fixes root pointer representation `""` rather than the erroneous `"/"`
- Fixes an issue where encoded tokens were not being resolved properly
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ keywords = ["json-pointer", "rfc-6901", "6901"]
license = "MIT OR Apache-2.0"
name = "jsonptr"
repository = "https://github.com/chanced/jsonptr"
version = "0.3.6"
version = "0.4.0"

[dependencies]
fluent-uri = { version = "0.1.4", optional = true, default-features = false }
Expand All @@ -18,5 +18,5 @@ uniresid = { version = "0.1.4", optional = true }
url = { version = "2", optional = true }

[features]
default = []
default = ["std"]
std = ["serde/std", "serde_json/std", "fluent-uri?/std"]
128 changes: 83 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,71 +12,105 @@ Data structures and logic for resolving, assigning, and deleting by JSON Pointer

JSON Pointers can be created either with a slice of strings or directly from a properly encoded string representing a JSON Pointer.

### Resolve
### Resolve values

#### `Pointer::resolve`

```rust
use jsonptr::Pointer;
use serde_json::json;

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

#### `Resolve::resolve`

```rust
use jsonptr::{Pointer, Resolve, ResolveMut};
use jsonptr::{Pointer, Resolve};
use serde_json::json;

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

let ptr = Pointer::new(&["foo", "bar"]);
let bar = ptr.resolve(&data).unwrap();
assert_eq!(bar, "baz");
```

let bar = data.resolve(&ptr).unwrap();
assert_eq!(bar, "baz");
#### `ResolveMut::resolve_mut`

let ptr = Pointer::try_from("/foo/bar").unwrap();
let mut bar = data.resolve_mut(&ptr).unwrap();
assert_eq!(bar, "baz");
}
```rust
use jsonptr::{Pointer, ResolveMut};
use serde_json::json;

let ptr = Pointer::try_from("/foo/bar").unwrap();
let mut data = json!({ "foo": { "bar": "baz" }});
let mut bar = data.resolve_mut(&ptr).unwrap();
assert_eq!(bar, "baz");
```

### Assign

#### `Pointer::assign`

```rust
use jsonptr::Pointer;
use serde_json::json;

let ptr = Pointer::try_from("/foo/bar").unwrap();
let mut data = json!({});
let _previous = ptr.assign(&mut data, "qux").unwrap();
assert_eq!(data, json!({ "foo": { "bar": "qux" }}))
```

#### `Assign::asign`

```rust
use jsonptr::{Pointer, Assign};
use jsonptr::{Assign, Pointer};
use serde_json::json;

fn main() {
let ptr = Pointer::try_from("/foo/bar").unwrap();
let mut data = json!({});
let assignment = data.assign(&ptr, "qux");
assert_eq!(data, json!({ "foo": { "bar": "qux" }}))
}
let ptr = Pointer::try_from("/foo/bar").unwrap();
let mut data = json!({});
let _previous = data.assign(&ptr, "qux").unwrap();
assert_eq!(data, json!({ "foo": { "bar": "qux" }}))
```

### Delete

#### `Pointer::delete`

```rust
use jsonptr::Pointer;
use serde_json::json;

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

// unresolved pointers return None
let mut data = json!({});
assert_eq!(ptr.delete(&mut data), None);
```

#### `Delete::delete`

```rust
use jsonptr::{Pointer, Delete};
use serde_json::json;
fn main() {
let mut data = json!({ "foo": { "bar": { "baz": "qux" } } });
let ptr = Pointer::new(&["foo", "bar", "baz"]);
assert_eq!(data.delete(&ptr), Ok(Some("qux".into())));
assert_eq!(data, json!({ "foo": { "bar": {} } }));

// unresolved pointers return Ok(None)
let mut data = json!({});
let ptr = Pointer::new(&["foo", "bar", "baz"]);
assert_eq!(ptr.delete(&mut data), Ok(None));
assert_eq!(data, json!({}));

// replacing a root pointer replaces data with `Value::Null`
let mut data = json!({ "foo": { "bar": "baz" } });
let ptr = Pointer::default();
let expected = json!({ "foo": { "bar": "baz" } });
assert_eq!(data.delete(&ptr), Ok(Some(expected)));
assert!(data.is_null());
}
use jsonptr::{Pointer, Delete};
use serde_json::json;

let mut data = json!({ "foo": { "bar": { "baz": "qux" } } });
let ptr = Pointer::new(["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 deleted = json!({ "foo": { "bar": {} } });
assert_eq!(data.delete(&ptr), Some(deleted));
assert!(data.is_null());
```

## Feature Flags
Expand All @@ -97,3 +131,7 @@ If you find an issue, please open a ticket or a pull request.
## License

MIT or Apache 2.0.

```
```
4 changes: 2 additions & 2 deletions src/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ pub trait Delete {
/// Error associated with `Delete`
type Error;
/// Attempts to internally delete a value based upon a [Pointer].
fn delete(&mut self, ptr: &Pointer) -> Result<Option<Value>, Self::Error>;
fn delete(&mut self, ptr: &Pointer) -> Option<Value>;
}

impl Delete for Value {
type Error = MalformedPointerError;
fn delete(&mut self, ptr: &Pointer) -> Result<Option<Value>, Self::Error> {
fn delete(&mut self, ptr: &Pointer) -> Option<Value> {
ptr.delete(self)
}
}
26 changes: 13 additions & 13 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ pub enum Error {
Unresolvable(UnresolvableError),
/// Indicates that a Pointer was not found in the data.
NotFound(NotFoundError),
/// Indicates that a Pointer was malformed.
MalformedPointer(MalformedPointerError),
// /// Indicates that a Pointer was malformed.
// MalformedPointer(MalformedPointerError),
}

impl Error {
Expand All @@ -41,16 +41,16 @@ impl Error {
pub fn is_not_found(&self) -> bool {
matches!(self, Error::NotFound(_))
}
/// Returns `true` if the error is `Error::MalformedPointerError`.
pub fn is_malformed_pointer(&self) -> bool {
matches!(self, Error::MalformedPointer(_))
}
}
impl From<MalformedPointerError> for Error {
fn from(err: MalformedPointerError) -> Self {
Error::MalformedPointer(err)
}
}
// /// Returns `true` if the error is `Error::MalformedPointerError`.
// pub fn is_malformed_pointer(&self) -> bool {
// matches!(self, Error::MalformedPointer(_))
// }
}
// impl From<MalformedPointerError> for Error {
// fn from(err: MalformedPointerError) -> Self {
// Error::MalformedPointer(err)
// }
// }
impl From<IndexError> for Error {
fn from(err: IndexError) -> Self {
Error::Index(err)
Expand Down Expand Up @@ -80,7 +80,7 @@ impl Display for Error {
Error::Index(err) => Display::fmt(err, f),
Error::Unresolvable(err) => Display::fmt(err, f),
Error::NotFound(err) => Display::fmt(err, f),
Error::MalformedPointer(err) => Display::fmt(err, f),
// Error::MalformedPointer(err) => Display::fmt(err, f),
}
}
}
Expand Down
Loading

0 comments on commit c1961df

Please sign in to comment.