diff --git a/serde_json_path_core/src/spec/integer.rs b/serde_json_path_core/src/spec/integer.rs index 6f7b647..1e5eda2 100644 --- a/serde_json_path_core/src/spec/integer.rs +++ b/serde_json_path_core/src/spec/integer.rs @@ -9,10 +9,17 @@ use std::{ str::FromStr, }; +/// An integer for internet JSON ([RFC7493][ijson]) +/// +/// The value must be within the range [-(253)+1, (253)-1]). +/// +/// [ijson]: https://www.rfc-editor.org/rfc/rfc7493#section-2.2 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Integer(i64); +/// The maximum allowed value, 2^53 - 1 const MAX: i64 = 9_007_199_254_740_992 - 1; +/// The minimum allowed value (-2^53) + 1 const MIN: i64 = -9_007_199_254_740_992 + 1; impl Integer { @@ -28,25 +35,37 @@ impl Integer { self.0 >= MIN && self.0 <= MAX } + /// Get an [`Integer`] from an `i64` + /// + /// This will produce `None` if the inputted value is out of the valid range + /// [-(253)+1, (253)-1]). pub fn from_i64_opt(value: i64) -> Option { Self::try_new(value).ok() } + /// Take the absolute value, producing `None` if the resulting value is outside + /// the valid range [-(253)+1, (253)-1]). pub fn checked_abs(mut self) -> Option { self.0 = self.0.checked_abs()?; self.check().then_some(self) } + /// Add the two values, producing `None` if the resulting value is outside the + /// valid range [-(253)+1, (253)-1]). pub fn checked_add(mut self, rhs: Self) -> Option { self.0 = self.0.checked_add(rhs.0)?; self.check().then_some(self) } + /// Subtract the `rhs` from `self`, producing `None` if the resulting value is + /// outside the valid range [-(253)+1, (253)-1]). pub fn checked_sub(mut self, rhs: Self) -> Option { self.0 = self.0.checked_sub(rhs.0)?; self.check().then_some(self) } + /// Multiply the two values, producing `None` if the resulting value is outside + /// the valid range [-(253)+1, (253)-1]). pub fn checked_mul(mut self, rhs: Self) -> Option { self.0 = self.0.checked_mul(rhs.0)?; self.check().then_some(self) @@ -111,10 +130,13 @@ impl PartialOrd for Integer { } } +/// An error for the [`Integer`] type #[derive(Debug, thiserror::Error)] pub enum IntegerError { + /// The provided value was outside the valid range [-(2**53)+1, (2**53)-1]) #[error("the provided integer was outside the valid range, see https://www.rfc-editor.org/rfc/rfc9535.html#section-2.1-4.1")] OutOfBounds, + /// Integer parsing error #[error(transparent)] Parse(#[from] ParseIntError), } diff --git a/serde_json_path_core/src/spec/selector/slice.rs b/serde_json_path_core/src/spec/selector/slice.rs index 7c08c04..8d260f1 100644 --- a/serde_json_path_core/src/spec/selector/slice.rs +++ b/serde_json_path_core/src/spec/selector/slice.rs @@ -50,17 +50,17 @@ impl Slice { } pub fn with_start(mut self, start: i64) -> Self { - self.start = Integer::from_i64_opt(start); + self.start = Some(Integer::from_i64_opt(start).expect("valid start")); self } pub fn with_end(mut self, end: i64) -> Self { - self.end = Integer::from_i64_opt(end); + self.end = Some(Integer::from_i64_opt(end).expect("valid end")); self } pub fn with_step(mut self, step: i64) -> Self { - self.step = Integer::from_i64_opt(step); + self.step = Some(Integer::from_i64_opt(step).expect("valid step")); self }