serde_valid/validation/numeric/
multiple_of.rs1use crate::validation::{impl_generic_composited_validation_1args, ValidateCompositedMultipleOf};
2use crate::MultipleOfError;
3
4pub trait ValidateMultipleOf<T>
45where
46 T: std::cmp::PartialEq + std::ops::Rem<Output = T> + num_traits::Zero,
47{
48 fn validate_multiple_of(&self, multiple_of: T) -> Result<(), crate::MultipleOfError>;
49}
50
51macro_rules! impl_validate_numeric_multiple_of {
52 ($type:ty) => {
53 impl ValidateMultipleOf<$type> for $type {
54 fn validate_multiple_of(
55 &self,
56 multiple_of: $type,
57 ) -> Result<(), crate::MultipleOfError> {
58 if std::cmp::PartialEq::<$type>::eq(
59 &(*self % multiple_of),
60 &num_traits::Zero::zero(),
61 ) {
62 Ok(())
63 } else {
64 Err(crate::MultipleOfError::new(multiple_of))
65 }
66 }
67 }
68
69 impl_generic_composited_validation_1args!(MultipleOf, $type);
70 };
71}
72
73impl_validate_numeric_multiple_of!(i8);
74impl_validate_numeric_multiple_of!(i16);
75impl_validate_numeric_multiple_of!(i32);
76impl_validate_numeric_multiple_of!(i64);
77#[cfg(feature = "i128")]
78impl_validate_numeric_multiple_of!(i128);
79impl_validate_numeric_multiple_of!(isize);
80impl_validate_numeric_multiple_of!(u8);
81impl_validate_numeric_multiple_of!(u16);
82impl_validate_numeric_multiple_of!(u32);
83impl_validate_numeric_multiple_of!(u64);
84#[cfg(feature = "i128")]
85impl_validate_numeric_multiple_of!(u128);
86impl_validate_numeric_multiple_of!(usize);
87impl_validate_numeric_multiple_of!(f32);
88impl_validate_numeric_multiple_of!(f64);
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 #[test]
95 fn test_validate_numeric_multiple_of_integer_is_true() {
96 assert!(ValidateMultipleOf::validate_multiple_of(&10i8, 5).is_ok());
97 assert!(ValidateMultipleOf::validate_multiple_of(&10i16, 5).is_ok());
98 assert!(ValidateMultipleOf::validate_multiple_of(&10i32, 5).is_ok());
99 assert!(ValidateMultipleOf::validate_multiple_of(&10i64, 5).is_ok());
100 assert!(ValidateMultipleOf::validate_multiple_of(&10isize, 5).is_ok());
101
102 assert!(ValidateMultipleOf::validate_multiple_of(&10u8, 5).is_ok());
103 assert!(ValidateMultipleOf::validate_multiple_of(&10u16, 5).is_ok());
104 assert!(ValidateMultipleOf::validate_multiple_of(&10u32, 5).is_ok());
105 assert!(ValidateMultipleOf::validate_multiple_of(&10u64, 5).is_ok());
106 assert!(ValidateMultipleOf::validate_multiple_of(&10usize, 5).is_ok());
107 }
108
109 #[test]
110 fn test_validate_numeric_multiple_of_integer_is_false() {
111 assert!(ValidateMultipleOf::validate_multiple_of(&10, 3).is_err());
112 assert!(ValidateMultipleOf::validate_multiple_of(&10i8, 3).is_err());
113 assert!(ValidateMultipleOf::validate_multiple_of(&10i16, 3).is_err());
114 assert!(ValidateMultipleOf::validate_multiple_of(&10i32, 3).is_err());
115 assert!(ValidateMultipleOf::validate_multiple_of(&10i64, 3).is_err());
116 assert!(ValidateMultipleOf::validate_multiple_of(&10isize, 3).is_err());
117
118 assert!(ValidateMultipleOf::validate_multiple_of(&10u8, 3).is_err());
119 assert!(ValidateMultipleOf::validate_multiple_of(&10u16, 3).is_err());
120 assert!(ValidateMultipleOf::validate_multiple_of(&10u32, 3).is_err());
121 assert!(ValidateMultipleOf::validate_multiple_of(&10u64, 3).is_err());
122 assert!(ValidateMultipleOf::validate_multiple_of(&10usize, 3).is_err());
123 }
124
125 #[test]
126 fn test_validate_numeric_multiple_of_float_is_true() {
127 assert!(ValidateMultipleOf::validate_multiple_of(&12.0, 1.0).is_ok());
128 assert!(ValidateMultipleOf::validate_multiple_of(&12.5, 0.5).is_ok());
129 }
130
131 #[test]
132 fn test_validate_numeric_multiple_of_float_is_false() {
133 assert!(ValidateMultipleOf::validate_multiple_of(&12.0, 5.0).is_err());
134 assert!(ValidateMultipleOf::validate_multiple_of(&12.5, 0.3).is_err());
135 }
136
137 #[test]
138 #[cfg(feature = "i128")]
139 fn test_validate_numeric_multiple_of_128bit_integer_is_true() {
140 assert!(ValidateMultipleOf::validate_multiple_of(&10i128, 5).is_ok());
141 assert!(ValidateMultipleOf::validate_multiple_of(&10u128, 5).is_ok());
142 }
143
144 #[test]
145 #[cfg(feature = "i128")]
146 fn test_validate_numeric_multiple_of_128bit_integer_is_false() {
147 assert!(ValidateMultipleOf::validate_multiple_of(&10i128, 3).is_err());
148 assert!(ValidateMultipleOf::validate_multiple_of(&10u128, 3).is_err());
149 }
150}