serde_valid/
error.rs

1use itertools::Itertools;
2use serde_valid_literal::Literal;
3
4use crate::validation::error::FormatDefault;
5use crate::validation::Number;
6
7#[derive(Debug, thiserror::Error)]
8pub enum Error<E>
9where
10    E: 'static + std::error::Error,
11{
12    #[error(transparent)]
13    DeserializeError(#[from] E),
14
15    #[error(transparent)]
16    ValidationError(crate::validation::Errors<crate::validation::Error>),
17}
18
19impl<E> Error<E>
20where
21    E: 'static + std::error::Error,
22{
23    pub fn is_serde_error(&self) -> bool {
24        match self {
25            Self::DeserializeError(_) => true,
26            Self::ValidationError(_) => false,
27        }
28    }
29
30    pub fn as_serde_error(&self) -> Option<&E> {
31        match self {
32            Self::DeserializeError(error) => Some(error),
33            Self::ValidationError(_) => None,
34        }
35    }
36
37    pub fn is_validation_errors(&self) -> bool {
38        match self {
39            Self::DeserializeError(_) => false,
40            Self::ValidationError(_) => true,
41        }
42    }
43
44    pub fn as_validation_errors(&self) -> Option<&crate::validation::Errors> {
45        match self {
46            Self::DeserializeError(_) => None,
47            Self::ValidationError(error) => Some(error),
48        }
49    }
50}
51
52macro_rules! struct_error_params {
53    (
54        #[derive(Debug, Clone)]
55        #[default_message=$default_message:literal]
56        pub struct $Error:ident {
57            pub $limit:ident: Vec<$type:ty>,
58        }
59    ) => {
60        #[derive(Debug, Clone)]
61        pub struct $Error {
62            pub $limit: Vec<$type>,
63        }
64
65        impl $Error {
66            pub fn new<T>($limit: &[T]) -> Self
67            where
68                T: Into<$type> + std::fmt::Debug + Clone,
69            {
70                Self {
71                    $limit: (*$limit).iter().map(|x| x.clone().into()).collect(),
72                }
73            }
74        }
75
76        impl FormatDefault for $Error {
77            #[inline]
78            fn format_default(&self) -> String {
79                format!(
80                    $default_message,
81                    self.$limit.iter().map(|v| format!("{}", v)).join(", ")
82                )
83            }
84        }
85    };
86
87    (
88        #[derive(Debug, Clone)]
89        #[default_message=$default_message:literal]
90        pub struct $Error:ident {
91            pub $limit:ident: $type:ty,
92        }
93    ) => {
94        #[derive(Debug, Clone)]
95        pub struct $Error {
96            pub $limit: $type,
97        }
98
99        impl $Error {
100            pub fn new<N: Into<$type>>($limit: N) -> Self {
101                Self {
102                    $limit: $limit.into(),
103                }
104            }
105        }
106
107        impl FormatDefault for $Error {
108            #[inline]
109            fn format_default(&self) -> String {
110                format!($default_message, self.$limit)
111            }
112        }
113    };
114
115    (
116        #[derive(Debug, Clone)]
117        #[default_message=$default_message:literal]
118        pub struct $Error:ident;
119    ) => {
120        #[derive(Debug, Clone)]
121        pub struct $Error;
122
123        impl FormatDefault for $Error {
124            #[inline]
125            fn format_default(&self) -> String {
126                format!($default_message)
127            }
128        }
129    };
130}
131
132// Number
133struct_error_params!(
134    #[derive(Debug, Clone)]
135    #[default_message = "The number must be `>= {}`."]
136    pub struct MinimumError {
137        pub minimum: Number,
138    }
139);
140
141struct_error_params!(
142    #[derive(Debug, Clone)]
143    #[default_message = "The number must be `<= {}`."]
144    pub struct MaximumError {
145        pub maximum: Number,
146    }
147);
148
149struct_error_params!(
150    #[derive(Debug, Clone)]
151    #[default_message = "The number must be `> {}`."]
152    pub struct ExclusiveMinimumError {
153        pub exclusive_minimum: Number,
154    }
155);
156
157struct_error_params!(
158    #[derive(Debug, Clone)]
159    #[default_message = "The number must be `< {}`."]
160    pub struct ExclusiveMaximumError {
161        pub exclusive_maximum: Number,
162    }
163);
164
165struct_error_params!(
166    #[derive(Debug, Clone)]
167    #[default_message = "The value must be multiple of `{}`."]
168    pub struct MultipleOfError {
169        pub multiple_of: Number,
170    }
171);
172
173// String
174struct_error_params!(
175    #[derive(Debug, Clone)]
176    #[default_message = "The length of the value must be `>= {}`."]
177    pub struct MinLengthError {
178        pub min_length: usize,
179    }
180);
181
182struct_error_params!(
183    #[derive(Debug, Clone)]
184    #[default_message = "The length of the value must be `<= {}`."]
185    pub struct MaxLengthError {
186        pub max_length: usize,
187    }
188);
189
190struct_error_params!(
191    #[derive(Debug, Clone)]
192    #[default_message = "The value must match the pattern of \"{0}\"."]
193    pub struct PatternError {
194        pub pattern: String,
195    }
196);
197
198// Array
199struct_error_params!(
200    #[derive(Debug, Clone)]
201    #[default_message = "The length of the items must be `<= {}`."]
202    pub struct MaxItemsError {
203        pub max_items: usize,
204    }
205);
206
207struct_error_params!(
208    #[derive(Debug, Clone)]
209    #[default_message = "The length of the items must be `>= {}`."]
210    pub struct MinItemsError {
211        pub min_items: usize,
212    }
213);
214
215struct_error_params!(
216    #[derive(Debug, Clone)]
217    #[default_message = "The items must be unique."]
218    pub struct UniqueItemsError;
219);
220
221// Object
222struct_error_params!(
223    #[derive(Debug, Clone)]
224    #[default_message = "The size of the properties must be `<= {}`."]
225    pub struct MaxPropertiesError {
226        pub max_properties: usize,
227    }
228);
229
230struct_error_params!(
231    #[derive(Debug, Clone)]
232    #[default_message = "The size of the properties must be `>= {}`."]
233    pub struct MinPropertiesError {
234        pub min_properties: usize,
235    }
236);
237
238// Generic
239struct_error_params!(
240    #[derive(Debug, Clone)]
241    #[default_message = "The value must be in [{:}]."]
242    pub struct EnumerateError {
243        pub enumerate: Vec<Literal>,
244    }
245);