serde_valid/validation/
composited.rs

1use crate::validation::error::IntoError;
2
3use crate::error::{
4    EnumerateError, ExclusiveMaximumError, ExclusiveMinimumError, MaxItemsError, MaxLengthError,
5    MaxPropertiesError, MaximumError, MinItemsError, MinLengthError, MinPropertiesError,
6    MinimumError, MultipleOfError, PatternError, UniqueItemsError,
7};
8use indexmap::IndexMap;
9
10/// Composited use Vec or Map error.
11///
12/// Composited elevates field validation errors to per-element error in the array.
13///
14/// # Examples
15/// ```rust
16/// use serde_valid::Validate;
17///
18/// #[derive(Validate)]
19/// pub struct Data {
20///     #[validate(minimum = 0)]
21///     #[validate(maximum = 10)]
22///     pub val: Vec<i32>, // <-- Here
23/// }
24/// ```
25#[derive(Debug)]
26pub enum Composited<Error> {
27    Single(Error),
28    Array(IndexMap<usize, Composited<Error>>),
29}
30
31macro_rules! impl_into_error {
32    ($ErrorType:ident) => {
33        paste::paste! {
34            impl IntoError<[<$ErrorType Error>]> for Composited<[<$ErrorType Error>]> {
35                fn into_error_by(self, format: crate::validation::error::Format<[<$ErrorType Error>]>) -> crate::validation::error::Error {
36                    match self {
37                        Composited::Single(single) => {
38                            crate::validation::error::Error::$ErrorType(format.into_message(single))
39                        },
40                        Composited::Array(array) =>{
41                            crate::validation::error::Error::Items(crate::validation::error::ArrayErrors::new(
42                            Vec::with_capacity(0),
43                            array
44                                .into_iter()
45                                .map(|(index, params)| {
46                                    (index, crate::validation::Errors::NewType(vec![params.into_error_by(format.clone())]))
47                                })
48                                .collect::<IndexMap<_, _>>(),
49                        ))},
50                    }
51                }
52            }
53        }
54    };
55}
56
57// Global
58impl_into_error!(Enumerate);
59
60// Numeric
61impl_into_error!(Maximum);
62impl_into_error!(Minimum);
63impl_into_error!(ExclusiveMaximum);
64impl_into_error!(ExclusiveMinimum);
65impl_into_error!(MultipleOf);
66
67// String
68impl_into_error!(MaxLength);
69impl_into_error!(MinLength);
70impl_into_error!(Pattern);
71
72// Array
73impl_into_error!(MaxItems);
74impl_into_error!(MinItems);
75impl_into_error!(UniqueItems);
76
77// Object
78impl_into_error!(MaxProperties);
79impl_into_error!(MinProperties);