serde_valid/validation/numeric/
exclusive_minimum.rs

1use crate::validation::{
2    impl_generic_composited_validation_1args, ValidateCompositedExclusiveMinimum,
3};
4use crate::ExclusiveMinimumError;
5
6/// Exclusive minimum 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, ValidateExclusiveMinimum};
13/// struct MyType(i32);
14///
15/// impl ValidateExclusiveMinimum<i32> for MyType {
16///     fn validate_exclusive_minimum(&self, exclusive_minimum: i32) -> Result<(), serde_valid::ExclusiveMinimumError> {
17///         self.0.validate_exclusive_minimum(exclusive_minimum)
18///     }
19/// }
20///
21/// #[derive(Validate)]
22/// struct TestStruct {
23///     #[validate(exclusive_minimum = 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 ValidateExclusiveMinimum<T>
43where
44    T: PartialOrd + PartialEq,
45{
46    fn validate_exclusive_minimum(&self, exclusive_minimum: T)
47        -> Result<(), ExclusiveMinimumError>;
48}
49
50macro_rules! impl_validate_numeric_exclusive_minimum {
51    ($type:ty) => {
52        impl ValidateExclusiveMinimum<$type> for $type {
53            fn validate_exclusive_minimum(
54                &self,
55                exclusive_minimum: $type,
56            ) -> Result<(), ExclusiveMinimumError> {
57                if *self > exclusive_minimum {
58                    Ok(())
59                } else {
60                    Err(ExclusiveMinimumError::new(exclusive_minimum))
61                }
62            }
63        }
64
65        impl_generic_composited_validation_1args!(ExclusiveMinimum, $type);
66    };
67}
68
69impl_validate_numeric_exclusive_minimum!(i8);
70impl_validate_numeric_exclusive_minimum!(i16);
71impl_validate_numeric_exclusive_minimum!(i32);
72impl_validate_numeric_exclusive_minimum!(i64);
73#[cfg(feature = "i128")]
74impl_validate_numeric_exclusive_minimum!(i128);
75impl_validate_numeric_exclusive_minimum!(isize);
76impl_validate_numeric_exclusive_minimum!(u8);
77impl_validate_numeric_exclusive_minimum!(u16);
78impl_validate_numeric_exclusive_minimum!(u32);
79impl_validate_numeric_exclusive_minimum!(u64);
80#[cfg(feature = "i128")]
81impl_validate_numeric_exclusive_minimum!(u128);
82impl_validate_numeric_exclusive_minimum!(usize);
83impl_validate_numeric_exclusive_minimum!(std::num::NonZeroI8);
84impl_validate_numeric_exclusive_minimum!(std::num::NonZeroI16);
85impl_validate_numeric_exclusive_minimum!(std::num::NonZeroI32);
86impl_validate_numeric_exclusive_minimum!(std::num::NonZeroI64);
87#[cfg(feature = "i128")]
88impl_validate_numeric_exclusive_minimum!(std::num::NonZeroI128);
89impl_validate_numeric_exclusive_minimum!(std::num::NonZeroIsize);
90impl_validate_numeric_exclusive_minimum!(std::num::NonZeroU8);
91impl_validate_numeric_exclusive_minimum!(std::num::NonZeroU16);
92impl_validate_numeric_exclusive_minimum!(std::num::NonZeroU32);
93impl_validate_numeric_exclusive_minimum!(std::num::NonZeroU64);
94#[cfg(feature = "i128")]
95impl_validate_numeric_exclusive_minimum!(std::num::NonZeroU128);
96impl_validate_numeric_exclusive_minimum!(std::num::NonZeroUsize);
97impl_validate_numeric_exclusive_minimum!(f32);
98impl_validate_numeric_exclusive_minimum!(f64);
99
100#[cfg(test)]
101mod tests {
102    use super::*;
103
104    #[test]
105    fn test_validate_numeric_exclusive_minimum_is_true() {
106        // Unspecified generic type:
107        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(&10, 9).is_ok());
108    }
109
110    #[test]
111    fn test_validate_numeric_exclusive_minimum_is_false() {
112        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(&10, 11).is_err());
113        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(&10, 10).is_err());
114    }
115
116    #[test]
117    fn test_validate_numeric_exclusive_minimum_specified_type() {
118        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(&10, 9i8).is_ok());
119        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(&10, 9i16).is_ok());
120        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(&10, 9i32).is_ok());
121        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(&10, 9i64).is_ok());
122        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(&10, 9isize).is_ok());
123
124        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(&10, 9u8).is_ok());
125        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(&10, 9u16).is_ok());
126        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(&10, 9u32).is_ok());
127        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(&10, 9u64).is_ok());
128        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(&10, 9usize).is_ok());
129
130        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(
131            &std::num::NonZeroI8::new(10).unwrap(),
132            std::num::NonZeroI8::new(9).unwrap()
133        )
134        .is_ok());
135        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(
136            &std::num::NonZeroI16::new(10).unwrap(),
137            std::num::NonZeroI16::new(9).unwrap()
138        )
139        .is_ok());
140        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(
141            &std::num::NonZeroI32::new(10).unwrap(),
142            std::num::NonZeroI32::new(9).unwrap()
143        )
144        .is_ok());
145        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(
146            &std::num::NonZeroI64::new(10).unwrap(),
147            std::num::NonZeroI64::new(9).unwrap()
148        )
149        .is_ok());
150        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(
151            &std::num::NonZeroIsize::new(10).unwrap(),
152            std::num::NonZeroIsize::new(9).unwrap()
153        )
154        .is_ok());
155
156        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(
157            &std::num::NonZeroU8::new(10).unwrap(),
158            std::num::NonZeroU8::new(9).unwrap()
159        )
160        .is_ok());
161        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(
162            &std::num::NonZeroU16::new(10).unwrap(),
163            std::num::NonZeroU16::new(9).unwrap()
164        )
165        .is_ok());
166        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(
167            &std::num::NonZeroU32::new(10).unwrap(),
168            std::num::NonZeroU32::new(9).unwrap()
169        )
170        .is_ok());
171        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(
172            &std::num::NonZeroU64::new(10).unwrap(),
173            std::num::NonZeroU64::new(9).unwrap()
174        )
175        .is_ok());
176        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(
177            &std::num::NonZeroUsize::new(10).unwrap(),
178            std::num::NonZeroUsize::new(9).unwrap()
179        )
180        .is_ok());
181
182        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(&10.0, 9.9f32).is_ok());
183        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(&10.0, 9.9f64).is_ok());
184    }
185
186    #[test]
187    #[cfg(feature = "i128")]
188    fn test_validate_numeric_exclusive_minimum_128() {
189        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(&10, 9i128).is_ok());
190        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(&10, 9u128).is_ok());
191
192        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(
193            &std::num::NonZeroI128::new(10).unwrap(),
194            std::num::NonZeroI128::new(9).unwrap()
195        )
196        .is_ok());
197        assert!(ValidateExclusiveMinimum::validate_exclusive_minimum(
198            &std::num::NonZeroU128::new(10).unwrap(),
199            std::num::NonZeroU128::new(9).unwrap()
200        )
201        .is_ok());
202    }
203}