-
Notifications
You must be signed in to change notification settings - Fork 7
Adds position to AssignError, ResolveError variants, renames both errors to be less redundant
#93
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
Changes from 1 commit
45c4fde
e892a48
5dbf330
0b60a5c
b48e05b
16731e1
78704a4
1845e56
8699be5
f69fa55
112fec5
b78f2a6
516e9b3
8550151
f507257
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -133,55 +133,66 @@ pub trait Assign { | |
| ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ | ||
| ╔══════════════════════════════════════════════════════════════════════════════╗ | ||
| ║ ║ | ||
| ║ AssignError ║ | ||
| ║ ¯¯¯¯¯¯¯¯¯¯¯¯¯ ║ | ||
| ║ Error ║ | ||
| ║ ¯¯¯¯¯¯¯ ║ | ||
| ╚══════════════════════════════════════════════════════════════════════════════╝ | ||
| ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ | ||
| */ | ||
|
|
||
| // TODO: should AssignError be deprecated? | ||
| /// Alias for [`Error`]. | ||
| /// | ||
| /// Possible error returned from [`Assign`] implementations for | ||
| /// [`serde_json::Value`] and | ||
| /// [`toml::Value`](https://docs.rs/toml/0.8.14/toml/index.html). | ||
| pub type AssignError = Error; | ||
|
|
||
| /// Possible error returned from [`Assign`] implementations for | ||
| /// [`serde_json::Value`] and | ||
| /// [`toml::Value`](https://docs.rs/toml/0.8.14/toml/index.html). | ||
| #[derive(Debug, PartialEq, Eq)] | ||
| pub enum AssignError { | ||
| /// A `Token` within the `Pointer` failed to be parsed as an array index. | ||
| pub enum Error { | ||
| /// A [`Token`] within the [`Pointer`] failed to be parsed as an array index. | ||
| FailedToParseIndex { | ||
| /// Position (index) of the token which failed to parse as an `Index` | ||
chanced marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| position: usize, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume this is to aid with the error message, right? Thinking about it, we could technically derive it on-the-fly from the offset + token. I know this was part of the raison d'etre for this PR, but I just realised I don't really understand the motivation. |
||
| /// Offset of the partial pointer starting with the invalid index. | ||
| offset: usize, | ||
| /// The source [`ParseIndexError`] | ||
| source: ParseIndexError, | ||
| }, | ||
|
|
||
| /// target array. | ||
| /// A [`Token`] within the [`Pointer`] contains an [`Index`] which is out of bounds. | ||
| /// | ||
| /// The current or resulting array's length is less than the index. | ||
| OutOfBounds { | ||
| /// Position (index) of the token which failed to parse as an `Index` | ||
| position: usize, | ||
| /// Offset of the partial pointer starting with the invalid index. | ||
| offset: usize, | ||
| /// The source [`OutOfBoundsError`] | ||
| source: OutOfBoundsError, | ||
| }, | ||
| } | ||
|
|
||
| impl fmt::Display for AssignError { | ||
| impl fmt::Display for Error { | ||
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
| match self { | ||
| Self::FailedToParseIndex { offset, .. } => { | ||
| write!( | ||
| f, | ||
| "assignment failed due to an invalid index at offset {offset}" | ||
| ) | ||
| Self::FailedToParseIndex { .. } => { | ||
| write!(f, "assignment failed due to an invalid index") | ||
|
||
| } | ||
| Self::OutOfBounds { offset, .. } => { | ||
| Self::OutOfBounds { .. } => { | ||
| write!( | ||
| f, | ||
| "assignment failed due to index at offset {offset} being out of bounds" | ||
| "assignment failed due to index an index being out of bounds" | ||
| ) | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #[cfg(feature = "std")] | ||
| impl std::error::Error for AssignError { | ||
| impl std::error::Error for Error { | ||
| fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { | ||
| match self { | ||
| Self::FailedToParseIndex { source, .. } => Some(source), | ||
|
|
@@ -207,7 +218,7 @@ enum Assigned<'v, V> { | |
|
|
||
| #[cfg(feature = "json")] | ||
| mod json { | ||
| use super::{Assign, AssignError, Assigned}; | ||
| use super::{Assign, Assigned, Error}; | ||
| use crate::{Pointer, Token}; | ||
| use alloc::{ | ||
| string::{String, ToString}, | ||
|
|
@@ -235,7 +246,7 @@ mod json { | |
| } | ||
| impl Assign for Value { | ||
| type Value = Value; | ||
| type Error = AssignError; | ||
| type Error = Error; | ||
| fn assign<V>(&mut self, ptr: &Pointer, value: V) -> Result<Option<Self::Value>, Self::Error> | ||
| where | ||
| V: Into<Self::Value>, | ||
|
|
@@ -248,14 +259,15 @@ mod json { | |
| mut ptr: &Pointer, | ||
| mut dest: &mut Value, | ||
| mut value: Value, | ||
| ) -> Result<Option<Value>, AssignError> { | ||
| ) -> Result<Option<Value>, Error> { | ||
| let mut offset = 0; | ||
|
|
||
| let mut position = 0; | ||
| while let Some((token, tail)) = ptr.split_front() { | ||
| let tok_len = token.encoded().len(); | ||
|
|
||
| let assigned = match dest { | ||
| Value::Array(array) => assign_array(token, tail, array, value, offset)?, | ||
| Value::Array(array) => assign_array(token, tail, array, value, position, offset)?, | ||
| Value::Object(obj) => assign_object(token, tail, obj, value), | ||
| _ => assign_scalar(ptr, dest, value), | ||
| }; | ||
|
|
@@ -273,6 +285,7 @@ mod json { | |
| } | ||
| } | ||
| offset += 1 + tok_len; | ||
| position += 1; | ||
| } | ||
|
|
||
| // Pointer is root, we can replace `dest` directly | ||
|
|
@@ -285,14 +298,23 @@ mod json { | |
| remaining: &Pointer, | ||
| array: &'v mut Vec<Value>, | ||
| src: Value, | ||
| position: usize, | ||
| offset: usize, | ||
| ) -> Result<Assigned<'v, Value>, AssignError> { | ||
| ) -> Result<Assigned<'v, Value>, Error> { | ||
| // parsing the index | ||
| let idx = token | ||
| .to_index() | ||
| .map_err(|source| AssignError::FailedToParseIndex { offset, source })? | ||
| .map_err(|source| Error::FailedToParseIndex { | ||
| position, | ||
| offset, | ||
| source, | ||
| })? | ||
| .for_len_incl(array.len()) | ||
| .map_err(|source| AssignError::OutOfBounds { offset, source })?; | ||
| .map_err(|source| Error::OutOfBounds { | ||
| position, | ||
| offset, | ||
| source, | ||
| })?; | ||
|
|
||
| debug_assert!(idx <= array.len()); | ||
|
|
||
|
|
@@ -381,7 +403,7 @@ mod json { | |
|
|
||
| #[cfg(feature = "toml")] | ||
| mod toml { | ||
| use super::{Assign, AssignError, Assigned}; | ||
| use super::{Assign, Assigned, Error}; | ||
| use crate::{Pointer, Token}; | ||
| use alloc::{string::String, vec, vec::Vec}; | ||
| use core::mem; | ||
|
|
@@ -406,7 +428,7 @@ mod toml { | |
|
|
||
| impl Assign for Value { | ||
| type Value = Value; | ||
| type Error = AssignError; | ||
| type Error = Error; | ||
| fn assign<V>(&mut self, ptr: &Pointer, value: V) -> Result<Option<Self::Value>, Self::Error> | ||
| where | ||
| V: Into<Self::Value>, | ||
|
|
@@ -419,14 +441,15 @@ mod toml { | |
| mut ptr: &Pointer, | ||
| mut dest: &mut Value, | ||
| mut value: Value, | ||
| ) -> Result<Option<Value>, AssignError> { | ||
| ) -> Result<Option<Value>, Error> { | ||
| let mut offset = 0; | ||
| let mut position = 0; | ||
|
|
||
| while let Some((token, tail)) = ptr.split_front() { | ||
| let tok_len = token.encoded().len(); | ||
|
|
||
| let assigned = match dest { | ||
| Value::Array(array) => assign_array(token, tail, array, value, offset)?, | ||
| Value::Array(array) => assign_array(token, tail, array, value, position, offset)?, | ||
| Value::Table(tbl) => assign_object(token, tail, tbl, value), | ||
| _ => assign_scalar(ptr, dest, value), | ||
| }; | ||
|
|
@@ -444,6 +467,7 @@ mod toml { | |
| } | ||
| } | ||
| offset += 1 + tok_len; | ||
| position += 1; | ||
| } | ||
|
|
||
| // Pointer is root, we can replace `dest` directly | ||
|
|
@@ -457,14 +481,23 @@ mod toml { | |
| remaining: &Pointer, | ||
| array: &'v mut Vec<Value>, | ||
| src: Value, | ||
| position: usize, | ||
| offset: usize, | ||
| ) -> Result<Assigned<'v, Value>, AssignError> { | ||
| ) -> Result<Assigned<'v, Value>, Error> { | ||
| // parsing the index | ||
| let idx = token | ||
| .to_index() | ||
| .map_err(|source| AssignError::FailedToParseIndex { offset, source })? | ||
| .map_err(|source| Error::FailedToParseIndex { | ||
| position, | ||
| offset, | ||
| source, | ||
| })? | ||
| .for_len_incl(array.len()) | ||
| .map_err(|source| AssignError::OutOfBounds { offset, source })?; | ||
| .map_err(|source| Error::OutOfBounds { | ||
| position, | ||
| offset, | ||
| source, | ||
| })?; | ||
|
|
||
| debug_assert!(idx <= array.len()); | ||
|
|
||
|
|
@@ -550,7 +583,7 @@ mod toml { | |
| #[cfg(test)] | ||
| #[allow(clippy::too_many_lines)] | ||
| mod tests { | ||
| use super::{Assign, AssignError}; | ||
| use super::{Assign, Error}; | ||
| use crate::{ | ||
| index::{OutOfBoundsError, ParseIndexError}, | ||
| Pointer, | ||
|
|
@@ -574,9 +607,6 @@ mod tests { | |
| V::Error: Debug + PartialEq, | ||
| Result<Option<V>, V::Error>: PartialEq<Result<Option<V::Value>, V::Error>>, | ||
| { | ||
| fn all(tests: impl IntoIterator<Item = Test<V>>) { | ||
| tests.into_iter().enumerate().for_each(|(i, t)| t.run(i)); | ||
| } | ||
| fn run(self, i: usize) { | ||
| let Test { | ||
| ptr, | ||
|
|
@@ -607,7 +637,7 @@ mod tests { | |
| fn assign_json() { | ||
| use alloc::vec; | ||
| use serde_json::json; | ||
| Test::all([ | ||
| [ | ||
| Test { | ||
| ptr: "/foo", | ||
| data: json!({}), | ||
|
|
@@ -731,7 +761,8 @@ mod tests { | |
| ptr: "/1", | ||
| data: json!([]), | ||
| assign: json!("foo"), | ||
| expected: Err(AssignError::OutOfBounds { | ||
| expected: Err(Error::OutOfBounds { | ||
| position: 0, | ||
| offset: 0, | ||
| source: OutOfBoundsError { | ||
| index: 1, | ||
|
|
@@ -751,7 +782,8 @@ mod tests { | |
| ptr: "/a", | ||
| data: json!([]), | ||
| assign: json!("foo"), | ||
| expected: Err(AssignError::FailedToParseIndex { | ||
| expected: Err(Error::FailedToParseIndex { | ||
| position: 0, | ||
| offset: 0, | ||
| source: ParseIndexError::InvalidInteger(usize::from_str("foo").unwrap_err()), | ||
| }), | ||
|
|
@@ -761,7 +793,8 @@ mod tests { | |
| ptr: "/002", | ||
| data: json!([]), | ||
| assign: json!("foo"), | ||
| expected: Err(AssignError::FailedToParseIndex { | ||
| expected: Err(Error::FailedToParseIndex { | ||
| position: 0, | ||
| offset: 0, | ||
| source: ParseIndexError::LeadingZeros, | ||
| }), | ||
|
|
@@ -771,13 +804,17 @@ mod tests { | |
| ptr: "/+23", | ||
| data: json!([]), | ||
| assign: json!("foo"), | ||
| expected: Err(AssignError::FailedToParseIndex { | ||
| expected: Err(Error::FailedToParseIndex { | ||
| position: 0, | ||
| offset: 0, | ||
| source: ParseIndexError::InvalidCharacters("+".into()), | ||
| }), | ||
| expected_data: json!([]), | ||
| }, | ||
| ]); | ||
| ] | ||
| .into_iter() | ||
| .enumerate() | ||
| .for_each(|(i, t)| t.run(i)); | ||
| } | ||
|
|
||
| /* | ||
|
|
@@ -791,7 +828,7 @@ mod tests { | |
| fn assign_toml() { | ||
| use alloc::vec; | ||
| use toml::{toml, Table, Value}; | ||
| Test::all([ | ||
| [ | ||
| Test { | ||
| data: Value::Table(toml::Table::new()), | ||
| ptr: "/foo", | ||
|
|
@@ -910,7 +947,8 @@ mod tests { | |
| data: Value::Array(vec![]), | ||
| ptr: "/1", | ||
| assign: "foo".into(), | ||
| expected: Err(AssignError::OutOfBounds { | ||
| expected: Err(Error::OutOfBounds { | ||
| position: 0, | ||
| offset: 0, | ||
| source: OutOfBoundsError { | ||
| index: 1, | ||
|
|
@@ -923,12 +961,16 @@ mod tests { | |
| data: Value::Array(vec![]), | ||
| ptr: "/a", | ||
| assign: "foo".into(), | ||
| expected: Err(AssignError::FailedToParseIndex { | ||
| expected: Err(Error::FailedToParseIndex { | ||
| position: 0, | ||
| offset: 0, | ||
| source: ParseIndexError::InvalidInteger(usize::from_str("foo").unwrap_err()), | ||
| }), | ||
| expected_data: Value::Array(vec![]), | ||
| }, | ||
| ]); | ||
| ] | ||
| .into_iter() | ||
| .enumerate() | ||
| .for_each(|(i, t)| t.run(i)); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.