summary refs log tree commit diff stats
path: root/tests/common
diff options
context:
space:
mode:
Diffstat (limited to 'tests/common')
-rw-r--r--tests/common/errorfunc.rs66
-rw-r--r--tests/common/errorpanic.rs21
2 files changed, 83 insertions, 4 deletions
diff --git a/tests/common/errorfunc.rs b/tests/common/errorfunc.rs
index 926c94c..5fb5fb6 100644
--- a/tests/common/errorfunc.rs
+++ b/tests/common/errorfunc.rs
@@ -4,8 +4,11 @@
 // Documentation and comments licensed under CC BY-SA 4.0.
 
 use ::std::marker::PhantomData;
+use ::std::ops::Bound;
+use ::std::ops::RangeBounds;
 
-use ::iosonism::strcursor::ReadError;
+use ::iosonism::error::RangeError;
+use ::iosonism::error::ReadError;
 use ::iosonism::strcursor::StringReader;
 
 /// An error callback.
@@ -17,7 +20,7 @@ pub trait ErrorFunc<'a, C: StringReader<'a>> {
 pub struct ErrorCall<T>(PhantomData<T>);
 
 #[non_exhaustive]
-#[derive(PartialEq, Eq, Debug)]
+#[derive(PartialEq, Debug)]
 pub enum ErrorType<'a> {
     InvalidInteger(&'a str),
     ExpectedInteger,
@@ -29,6 +32,17 @@ pub enum ErrorType<'a> {
     ExpectedEndOfQuote,
     InvalidEscape(&'a str),
     ExpectedSymbol(&'a str),
+    RangeErrori32(RangeErrorT<i32>),
+    RangeErrori64(RangeErrorT<i64>),
+    RangeErrorf32(RangeErrorT<f32>),
+    RangeErrorf64(RangeErrorT<f64>),
+}
+
+#[derive(PartialEq, Debug)]
+pub struct RangeErrorT<T> {
+    pub value: T,
+    pub start: Bound<T>,
+    pub end: Bound<T>,
 }
 
 impl<T> ::std::fmt::Display for ErrorCall<T> {
@@ -46,6 +60,54 @@ impl<T> ::std::fmt::Debug for ErrorCall<T> {
 impl<T> ::std::error::Error for ErrorCall<T> {
 }
 
+impl<'a, C, R, T> RangeError<'a, C, i32, R> for ErrorCall<T>
+where C: StringReader<'a>, R: RangeBounds<i32>, T: ErrorFunc<'a, C> {
+    fn value_not_in_range(context: &C, from: &i32, range: &R) -> Self {
+        T::call(context, ErrorType::RangeErrori32(RangeErrorT {
+            value: *from,
+            start: range.start_bound().cloned(),
+            end: range.end_bound().cloned(),
+        }));
+        Self(PhantomData)
+    }
+}
+
+impl<'a, C, R, T> RangeError<'a, C, i64, R> for ErrorCall<T>
+where C: StringReader<'a>, R: RangeBounds<i64>, T: ErrorFunc<'a, C> {
+    fn value_not_in_range(context: &C, from: &i64, range: &R) -> Self {
+        T::call(context, ErrorType::RangeErrori64(RangeErrorT {
+            value: *from,
+            start: range.start_bound().cloned(),
+            end: range.end_bound().cloned(),
+        }));
+        Self(PhantomData)
+    }
+}
+
+impl<'a, C, R, T> RangeError<'a, C, f32, R> for ErrorCall<T>
+where C: StringReader<'a>, R: RangeBounds<f32>, T: ErrorFunc<'a, C> {
+    fn value_not_in_range(context: &C, from: &f32, range: &R) -> Self {
+        T::call(context, ErrorType::RangeErrorf32(RangeErrorT {
+            value: *from,
+            start: range.start_bound().cloned(),
+            end: range.end_bound().cloned(),
+        }));
+        Self(PhantomData)
+    }
+}
+
+impl<'a, C, R, T> RangeError<'a, C, f64, R> for ErrorCall<T>
+where C: StringReader<'a>, R: RangeBounds<f64>, T: ErrorFunc<'a, C> {
+    fn value_not_in_range(context: &C, from: &f64, range: &R) -> Self {
+        T::call(context, ErrorType::RangeErrorf64(RangeErrorT {
+            value: *from,
+            start: range.start_bound().cloned(),
+            end: range.end_bound().cloned(),
+        }));
+        Self(PhantomData)
+    }
+}
+
 impl<'a, C: StringReader<'a>, T> ReadError<'a, C> for ErrorCall<T>
 where T: ErrorFunc<'a, C> {
     fn invalid_integer(context: &C, from: &str) -> Self {
diff --git a/tests/common/errorpanic.rs b/tests/common/errorpanic.rs
index faef603..6b4254b 100644
--- a/tests/common/errorpanic.rs
+++ b/tests/common/errorpanic.rs
@@ -3,11 +3,12 @@
 // Licensed under the MIT license.
 // Documentation and comments licensed under CC BY-SA 4.0.
 
-use ::iosonism::strcursor::ReadError;
+use ::iosonism::error::RangeError;
+use ::iosonism::error::ReadError;
 use ::iosonism::strcursor::StringReader;
 
 /// An implementation of various Iosonism errors that just panics.
-#[derive(Debug)]
+#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub enum ErrorPanic {
     // uninhabitable!
 }
@@ -22,6 +23,22 @@ impl ::std::fmt::Display for ErrorPanic {
 impl ::std::error::Error for ErrorPanic {
 }
 
+impl<'a, C, T, R> RangeError<'a, C, T, R> for ErrorPanic
+where C: StringReader<'a>, T: ::std::fmt::Display, R: ::std::fmt::Debug {
+    fn value_not_in_range(context: &C, from: &T, range: &R) -> Self {
+        if !context.get_remaining().is_empty() {
+            panic!(
+                "value ({}) not in range: {:?} at ...{}",
+                from,
+                range,
+                context.get_remaining(),
+            );
+        } else {
+            panic!("value ({}) not in range: {:?}", from, range);
+        }
+    }
+}
+
 impl<'a, C: StringReader<'a>> ReadError<'a, C> for ErrorPanic {
     fn invalid_integer(context: &C, from: &str) -> Self {
         if !context.get_remaining().is_empty() {