Skip to content

Commit 806fb0e

Browse files
committed
fixes the pointer in UnresolvableError. Adds documentation.
1 parent de57228 commit 806fb0e

File tree

9 files changed

+335
-174
lines changed

9 files changed

+335
-174
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Data structures and logic for resolving, assigning, and deleting by JSON Pointer
1313
JSON Pointers can be created either with a slice of strings or directly from a properly encoded string representing a JSON Pointer.
1414

1515
```rust
16-
use jsonptr::{Pointer, ResolveMut};
16+
use jsonptr::{Pointer, Resolve, ResolveMut};
1717
use serde_json::json;
1818

1919
fn main() {

src/assign.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use serde_json::Value;
44

55
use crate::{Error, Pointer};
66

7-
/// Assign is implemented by types which can internally mutate data based on a
8-
/// `serde_json::Value`.
7+
/// Assign is implemented by types which can internally assign a
8+
/// `serde_json::Value` by a JSON Pointer.
99
pub trait Assign {
1010
type Error: std::error::Error + Send + Sync + 'static;
1111
/// Assign a value of based on the path provided by a JSON Pointer.
@@ -19,6 +19,7 @@ impl Assign for Value {
1919
}
2020
}
2121
#[derive(Debug)]
22+
/// The data structure returned from a successful call to `assign`.
2223
pub struct Assignment<'a> {
2324
/// The value that was assigned.
2425
///
@@ -64,5 +65,16 @@ pub struct Assignment<'a> {
6465
/// and you assigned `"new_value"` to `"/foo/bar/baz"`, then `created` would
6566
/// be `Some("/foo/bar")` as `"/foo/bar"` is the new path object.
6667
pub created_or_mutated: Pointer,
68+
/// A `Pointer` consisting of the path which was assigned.
69+
///
70+
/// ## Example
71+
/// ```rust
72+
/// use serde_json::json;
73+
/// use jsonptr::{Pointer, Assign};
74+
/// let mut data = json!({ "foo": ["zero"] });
75+
/// let mut ptr = Pointer::try_from("/foo/-").unwrap();
76+
/// let assignment = data.assign(&mut ptr, "one".into()).unwrap();
77+
/// assert_eq!(assignment.assigned_to, Pointer::try_from("/foo/1").unwrap());
78+
/// ```
6779
pub assigned_to: Pointer,
6880
}

src/delete.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use serde_json::Value;
22

33
use crate::{MalformedPointerError, Pointer};
4-
4+
/// Delete is implemented by types which can internally remove a value based on
5+
/// a JSON Pointer
56
pub trait Delete {
67
type Error;
78
fn delete(&mut self, ptr: &Pointer) -> Result<Option<Value>, Self::Error>;

src/error.rs

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ use std::{
44
fmt::{Debug, Display, Formatter},
55
num::ParseIntError,
66
};
7+
8+
/// An enum representing possible errors that can occur when resolving or
9+
/// mutating by a JSON Pointer.
710
#[derive(Debug, PartialEq, Eq)]
811
pub enum Error {
912
Index(IndexError),
@@ -13,15 +16,19 @@ pub enum Error {
1316
}
1417

1518
impl Error {
19+
/// Returns `true` if the error is `Error::IndexError`.
1620
pub fn is_index(&self) -> bool {
1721
matches!(self, Error::Index(_))
1822
}
23+
/// Returns `true` if the error is `Error::UnresolvableError`.
1924
pub fn is_unresolvable(&self) -> bool {
2025
matches!(self, Error::Unresolvable(_))
2126
}
27+
/// Returns `true` if the error is `Error::NotFoundError`.
2228
pub fn is_not_found(&self) -> bool {
2329
matches!(self, Error::NotFound(_))
2430
}
31+
/// Returns `true` if the error is `Error::MalformedPointerError`.
2532
pub fn is_malformed_pointer(&self) -> bool {
2633
matches!(self, Error::MalformedPointer(_))
2734
}
@@ -48,11 +55,6 @@ impl From<OutOfBoundsError> for Error {
4855
}
4956
}
5057

51-
// impl From<serde_json::Error> for Error {
52-
// fn from(err: serde_json::Error) -> Self {
53-
// Error::Serde(err)
54-
// }
55-
// }
5658
impl From<UnresolvableError> for Error {
5759
fn from(err: UnresolvableError) -> Self {
5860
Error::Unresolvable(err)
@@ -81,31 +83,50 @@ impl StdError for Error {
8183
}
8284
}
8385

86+
/// Represents an error that occurs when attempting to resolve a `Pointer` that
87+
/// encounters a leaf node (i.e. a scalar / null value) which is not the root
88+
/// of the `Pointer`.
89+
///
90+
/// ## Example
91+
/// ```rust
92+
/// use serde_json::json;
93+
/// use jsonptr::{Pointer, ResolveMut, Resolve, UnresolvableError};
94+
/// let mut data = json!({ "foo": "bar" });
95+
/// let ptr = Pointer::try_from("/foo/unreachable").unwrap();
96+
/// let err = data.resolve_mut(&ptr).unwrap_err();
97+
/// assert_eq!(err, UnresolvableError::new(ptr.clone()).into());
98+
/// ```
8499
#[derive(Clone, PartialEq, Eq, Debug)]
85100
pub struct UnresolvableError {
86-
pub unresolvable: Pointer,
101+
pub pointer: Pointer,
102+
pub leaf: Option<Token>,
87103
}
88104
impl UnresolvableError {
89-
pub fn new(unresolvable: Pointer) -> Self {
90-
Self { unresolvable }
105+
pub fn new(pointer: Pointer) -> Self {
106+
let leaf = if pointer.count() >= 2 {
107+
Some(pointer.get(pointer.count() - 2).unwrap())
108+
} else {
109+
None
110+
};
111+
Self { pointer, leaf }
91112
}
92113
}
93114

94115
impl Display for UnresolvableError {
95116
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
96117
write!(
97118
f,
98-
"can not resolve \"{}\" due to \"{}\" being a leaf node",
99-
self.unresolvable,
100-
self.unresolvable
101-
.front()
102-
.map_or("/".to_string(), |t| t.to_string())
119+
"can not resolve \"{}\" due to {} being a scalar value",
120+
self.pointer,
121+
self.leaf
122+
.as_deref()
123+
.map_or_else(|| "the root value".to_string(), |l| format!("\"{}\"", l))
103124
)
104125
}
105126
}
106127
#[derive(PartialEq, Eq)]
107128
pub enum IndexError {
108-
Parse(ParseError<ParseIntError>),
129+
Parse(ParseError),
109130
OutOfBounds(OutOfBoundsError),
110131
}
111132
impl Display for IndexError {
@@ -130,39 +151,32 @@ impl From<OutOfBoundsError> for IndexError {
130151
}
131152

132153
#[derive(PartialEq, Eq)]
133-
pub struct ParseError<T> {
134-
pub source: T,
154+
pub struct ParseError {
155+
pub source: ParseIntError,
135156
pub token: Token,
136157
}
137158

138-
impl<E> Display for ParseError<E>
139-
where
140-
E: StdError,
141-
{
159+
impl Display for ParseError {
142160
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
143161
write!(f, "{}", self.source)
144162
}
145163
}
146-
impl<E> Debug for ParseError<E>
147-
where
148-
E: StdError + 'static,
149-
{
164+
impl Debug for ParseError {
150165
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
151166
f.debug_struct("ParseError")
152167
.field("source", &self.source)
153168
.field("token", &self.token)
154169
.finish()
155170
}
156171
}
157-
impl<E> StdError for ParseError<E>
158-
where
159-
E: StdError + 'static + Send + Sync,
160-
{
172+
impl StdError for ParseError {
161173
fn source(&self) -> Option<&(dyn StdError + 'static)> {
162174
Some(&self.source)
163175
}
164176
}
165177

178+
/// Indicates that the `Pointer` contains an index of an array that is out of
179+
/// bounds.
166180
#[derive(Debug, PartialEq, Eq)]
167181
pub struct OutOfBoundsError {
168182
pub len: usize,
@@ -203,6 +217,7 @@ impl Display for MalformedPointerError {
203217

204218
impl StdError for MalformedPointerError {}
205219

220+
/// NotFoundError indicates that a Pointer was not found in the data.
206221
#[derive(Debug, PartialEq, Eq)]
207222
pub struct NotFoundError {
208223
pub pointer: Pointer,
@@ -222,6 +237,8 @@ impl Display for NotFoundError {
222237
}
223238
}
224239

240+
/// ReplaceTokenError is returned from `Pointer::replace_token` when the
241+
/// provided index is out of bounds.
225242
#[derive(Debug, PartialEq, Eq, Clone)]
226243
pub struct ReplaceTokenError {
227244
pub index: usize,

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![doc = include_str!("../README.md")]
12
mod pointer;
23
pub use pointer::*;
34
mod token;

0 commit comments

Comments
 (0)