serde_valid/validation/numeric/
exclusive_maximum.rs

1use crate::validation::{
2    impl_generic_composited_validation_1args, ValidateCompositedExclusiveMaximum,
3};
4use crate::ExclusiveMaximumError;
5
6/// Exclusive maximum validation of the number.
7///
8/// See <https://json-schema.org/understanding-json-schema/reference/numeric.html#range>
9///
10/// ```rust
11/// use serde_json::json;
12/// use serde_valid::{Validate, ValidateExclusiveMaximum};
13/// struct MyType(i32);
14///
15/// impl ValidateExclusiveMaximum<i32> for MyType {
16///     fn validate_exclusive_maximum(&self, exclusive_maximum: i32) -> Result<(), serde_valid::ExclusiveMaximumError> {
17///         self.0.validate_exclusive_maximum(exclusive_maximum)
18///     }
19/// }
20///
21/// #[derive(Validate)]
22/// struct TestStruct {
23///     #[validate(exclusive_maximum = 5)]
24///     val: MyType,
25/// }
26///
27/// let s = TestStruct { val: MyType(5) };
28///
29/// assert_eq!(
30///     s.validate().unwrap_err().to_string(),
31///     json!({
32///         "errors": [],
33///         "properties": {
34///             "val": {
35///                 "errors": ["The number must be `< 5`."]
36///             }
37///         }
38///     })
39///     .to_string()
40/// );
41/// ```
42pub trait ValidateExclusiveMaximum<T>
43where
44    T: PartialOrd + PartialEq,
45{
46    fn validate_exclusive_maximum(&self, exclusive_maximum: T)
47        -> Result<(), ExclusiveMaximumError>;
48}
49
50macro_rules! impl_validate_numeric_exclusive_maximum {
51    ($type:ty) => {
52        impl ValidateExclusiveMaximum<$type> for $type {
53            fn validate_exclusive_maximum(
54                &self,
55                exclusive_maximum: $type,
56            ) -> Result<(), crate::ExclusiveMaximumError> {
57                if *self < exclusive_maximum {
58                    Ok(())
59                } else {
60                    Err(crate::ExclusiveMaximumError::new(exclusive_maximum))
61                }
62            }
63        }
64
65        impl_generic_composited_validation_1args!(ExclusiveMaximum, $type);
66    };
67}
68
69impl_validate_numeric_exclusive_maximum!(i8);
70impl_validate_numeric_exclusive_maximum!(i16);
71impl_validate_numeric_exclusive_maximum!(i32);
72impl_validate_numeric_exclusive_maximum!(i64);
73#[cfg(feature = "i128")]
74impl_validate_numeric_exclusive_maximum!(i128);
75impl_validate_numeric_exclusive_maximum!(isize);
76impl_validate_numeric_exclusive_maximum!(u8);
77impl_validate_numeric_exclusive_maximum!(u16);
78impl_validate_numeric_exclusive_maximum!(u32);
79impl_validate_numeric_exclusive_maximum!(u64);
80#[cfg(feature = "i128")]
81impl_validate_numeric_exclusive_maximum!(u128);
82impl_validate_numeric_exclusive_maximum!(usize);
83impl_validate_numeric_exclusive_maximum!(std::num::NonZeroI8);
84impl_validate_numeric_exclusive_maximum!(std::num::NonZeroI16);
85impl_validate_numeric_exclusive_maximum!(std::num::NonZeroI32);
86impl_validate_numeric_exclusive_maximum!(std::num::NonZeroI64);
87#[cfg(feature = "i128")]
88impl_validate_numeric_exclusive_maximum!(std::num::NonZeroI128);
89impl_validate_numeric_exclusive_maximum!(std::num::NonZeroIsize);
90impl_validate_numeric_exclusive_maximum!(std::num::NonZeroU8);
91impl_validate_numeric_exclusive_maximum!(std::num::NonZeroU16);
92impl_validate_numeric_exclusive_maximum!(std::num::NonZeroU32);
93impl_validate_numeric_exclusive_maximum!(std::num::NonZeroU64);
94#[cfg(feature = "i128")]
95impl_validate_numeric_exclusive_maximum!(std::num::NonZeroU128);
96impl_validate_numeric_exclusive_maximum!(std::num::NonZeroUsize);
97impl_validate_numeric_exclusive_maximum!(f32);
98impl_validate_numeric_exclusive_maximum!(f64);
99
100#[cfg(test)]
101mod tests {
102    use super::*;
103
104    #[test]
105    fn test_validate_numeric_exclusive_maximum_is_true() {
106        // Unspecified generic type:
107        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(&10, 11).is_ok());
108    }
109
110    #[test]
111    fn test_validate_numeric_exclusive_maximum_is_false() {
112        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(&10, 9).is_err());
113        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(&10, 10).is_err());
114    }
115
116    #[test]
117    fn test_validate_numeric_exclusive_maximum_specified_type() {
118        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(&10, 11i8).is_ok());
119        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(&10, 11i16).is_ok());
120        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(&10, 11i32).is_ok());
121        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(&10, 11i64).is_ok());
122        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(&10, 11isize).is_ok());
123
124        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(&10, 11u8).is_ok());
125        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(&10, 11u16).is_ok());
126        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(&10, 11u32).is_ok());
127        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(&10, 11u64).is_ok());
128        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(&10, 11usize).is_ok());
129
130        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(
131            &std::num::NonZeroI8::new(10).unwrap(),
132            std::num::NonZeroI8::new(11).unwrap()
133        )
134        .is_ok());
135        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(
136            &std::num::NonZeroI16::new(10).unwrap(),
137            std::num::NonZeroI16::new(11).unwrap()
138        )
139        .is_ok());
140        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(
141            &std::num::NonZeroI32::new(10).unwrap(),
142            std::num::NonZeroI32::new(11).unwrap()
143        )
144        .is_ok());
145        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(
146            &std::num::NonZeroI64::new(10).unwrap(),
147            std::num::NonZeroI64::new(11).unwrap()
148        )
149        .is_ok());
150        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(
151            &std::num::NonZeroIsize::new(10).unwrap(),
152            std::num::NonZeroIsize::new(11).unwrap()
153        )
154        .is_ok());
155
156        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(
157            &std::num::NonZeroU8::new(10).unwrap(),
158            std::num::NonZeroU8::new(11).unwrap()
159        )
160        .is_ok());
161        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(
162            &std::num::NonZeroU16::new(10).unwrap(),
163            std::num::NonZeroU16::new(11).unwrap()
164        )
165        .is_ok());
166        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(
167            &std::num::NonZeroU32::new(10).unwrap(),
168            std::num::NonZeroU32::new(11).unwrap()
169        )
170        .is_ok());
171        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(
172            &std::num::NonZeroU64::new(10).unwrap(),
173            std::num::NonZeroU64::new(11).unwrap()
174        )
175        .is_ok());
176        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(
177            &std::num::NonZeroUsize::new(10).unwrap(),
178            std::num::NonZeroUsize::new(11).unwrap()
179        )
180        .is_ok());
181
182        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(&10.0, 10.1f32).is_ok());
183        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(&10.0, 10.1f64).is_ok());
184    }
185
186    #[test]
187    #[cfg(feature = "i128")]
188    fn test_validate_numeric_exclusive_maximum_128() {
189        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(&10, 11i128).is_ok());
190        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(&10, 11u128).is_ok());
191        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(
192            &std::num::NonZeroI128::new(10).unwrap(),
193            std::num::NonZeroI128::new(11).unwrap()
194        )
195        .is_ok());
196        assert!(ValidateExclusiveMaximum::validate_exclusive_maximum(
197            &std::num::NonZeroU128::new(10).unwrap(),
198            std::num::NonZeroU128::new(11).unwrap()
199        )
200        .is_ok());
201    }
202}