serde_valid/validation/
custom.rs

1/// This function is used to avoid [rustc(E0282)](https://doc.rust-lang.org/error_codes/E0282.html) error in `#[validate(custom = ...)]` validator on the struct.
2#[inline]
3pub fn wrap_closure_validation<T: ?Sized, M: IntoVecErrors>(
4    data: &T,
5    f: impl FnOnce(&T) -> Result<(), M>,
6) -> Result<(), Vec<crate::validation::Error>> {
7    f(data).map_err(|e| e.into_vec_errors())
8}
9
10#[inline]
11pub fn wrap_into_vec_errors<M: IntoVecErrors>(
12    result: Result<(), M>,
13) -> Result<(), Vec<crate::validation::Error>> {
14    result.map_err(|e| e.into_vec_errors())
15}
16
17pub trait IntoVecErrors {
18    fn into_vec_errors(self) -> Vec<crate::validation::Error>;
19}
20
21impl IntoVecErrors for Vec<crate::validation::Error> {
22    fn into_vec_errors(self) -> Vec<crate::validation::Error> {
23        self
24    }
25}
26
27impl IntoVecErrors for crate::validation::Error {
28    fn into_vec_errors(self) -> Vec<crate::validation::Error> {
29        vec![self]
30    }
31}
32
33#[cfg(test)]
34mod test {
35    use super::*;
36
37    #[test]
38    fn test_custom_fn_single_error() {
39        fn single_error(data: &i32) -> Result<(), crate::validation::Error> {
40            if *data > 0 {
41                Ok(())
42            } else {
43                Err(crate::validation::Error::Custom(
44                    "Value must be greater than 0".to_string(),
45                ))
46            }
47        }
48
49        assert!(wrap_closure_validation(&1i32, single_error).is_ok());
50        assert!(wrap_closure_validation(&0i32, single_error).is_err());
51        assert!(wrap_closure_validation(&-1i32, single_error).is_err());
52    }
53
54    #[test]
55    fn test_custom_fn_multiple_errors() {
56        fn multiple_errors(data: &i32) -> Result<(), Vec<crate::validation::Error>> {
57            let mut errors = Vec::new();
58            if *data < 1 {
59                errors.push(crate::validation::Error::Custom(
60                    "Value must be greater than 0".to_string(),
61                ));
62            }
63
64            if *data >= 10 {
65                errors.push(crate::validation::Error::Custom(
66                    "Value must be less than 10".to_string(),
67                ));
68            }
69
70            if errors.is_empty() {
71                Ok(())
72            } else {
73                Err(errors)
74            }
75        }
76
77        assert!(wrap_closure_validation(&1i32, multiple_errors).is_ok());
78        assert!(wrap_closure_validation(&10i32, multiple_errors).is_err());
79        assert!(wrap_closure_validation(&11i32, multiple_errors).is_err());
80        assert!(wrap_closure_validation(&0i32, multiple_errors).is_err());
81        assert!(wrap_closure_validation(&-1i32, multiple_errors).is_err());
82    }
83}