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
132struct_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
173struct_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
198struct_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
221struct_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
238struct_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);