1macro_rules! not_bool_schema {
7 ($schema:expr, $span:expr) => {
8 not_bool_schema!((), $schema, $span)
9 };
10 ($ret_val:expr, $schema:expr, $span:expr) => {
11 match &$schema {
12 SchemaRef::Bool(allow_all) => {
13 if *allow_all {
14 return Ok($ret_val);
15 } else {
16 let mut errors = ErrorsInner::new();
17 errors.push(Error::new(None, ($span).clone(), ErrorValue::Never));
18 return Err(Errors(errors));
19 }
20 }
21 SchemaRef::Object(o) => o,
22 }
23 };
24}
25
26macro_rules! check_type {
27 ($actual_type:ident, $schema:expr, $span:expr) => {
28 match &$schema.instance_type {
29 Some(s) => match s {
30 SingleOrVec::Single(single) => match &**single {
31 InstanceType::$actual_type => Ok(()),
32 _ => {
33 let mut errors = ErrorsInner::new();
34 errors.push(Error::new(
35 $schema.metadata.clone(),
36 $span.clone(),
37 ErrorValue::InvalidType {
38 expected: s.clone(),
39 actual: InstanceType::$actual_type,
40 },
41 ));
42 Err(Errors(errors))
43 }
44 },
45 SingleOrVec::Vec(vec) => {
46 if vec.iter().any(|i| *i == InstanceType::$actual_type) {
47 Ok(())
48 } else {
49 let mut errors = ErrorsInner::new();
50 errors.push(Error::new(
51 $schema.metadata.clone(),
52 $span.clone(),
53 ErrorValue::InvalidType {
54 expected: s.clone(),
55 actual: InstanceType::$actual_type,
56 },
57 ));
58 Err(Errors(errors))
59 }
60 }
61 },
62 None => {
63 let mut errors = ErrorsInner::new();
64 errors.push(Error::new(
65 $schema.metadata.clone(),
66 $span.clone(),
67 ErrorValue::InvalidType {
68 expected: SingleOrVec::Single(Box::new(InstanceType::Object)),
69 actual: InstanceType::$actual_type,
70 },
71 ));
72 Err(Errors(errors))
73 }
74 }
75 };
76 ($schema:expr, $span:expr) => {
77 match &$schema.instance_type {
78 Some(s) => match s {
79 SingleOrVec::Single(single) => match &**single {
80 InstanceType::Object => Ok(()),
81 _ => {
82 let mut errors = ErrorsInner::new();
83 errors.push(Error::new(
84 $schema.metadata.clone(),
85 $span.clone(),
86 ErrorValue::InvalidType {
87 expected: s.clone(),
88 actual: InstanceType::Object,
89 },
90 ));
91 Err(Errors(errors))
92 }
93 },
94 SingleOrVec::Vec(vec) => {
95 if vec.iter().any(|i| *i == InstanceType::Object) {
96 Ok(())
97 } else {
98 let mut errors = ErrorsInner::new();
99 errors.push(Error::new(
100 $schema.metadata.clone(),
101 $span.clone(),
102 ErrorValue::InvalidType {
103 expected: s.clone(),
104 actual: InstanceType::Object,
105 },
106 ));
107 Err(Errors(errors))
108 }
109 }
110 },
111 None => Ok(()),
112 }
113 };
114}
115
116macro_rules! check_enum {
117 (bool, $value:expr, $schema:expr, $span:expr) => {
118 if let Some(enum_vals) = &$schema.enum_values {
119 let mut enum_contains = false;
120 for val in enum_vals {
121 if let Some(v) = val.as_bool() {
122 if v == $value {
123 enum_contains = true;
124 break;
125 }
126 }
127 }
128
129 if enum_contains {
130 Ok(())
131 } else {
132 let mut errors = ErrorsInner::new();
133 errors.push(Error::new(
134 $schema.metadata.clone(),
135 $span.clone(),
136 ErrorValue::InvalidEnumValue {
137 expected: enum_vals.clone(),
138 },
139 ));
140 Err(Errors(errors))
141 }
142 } else {
143 Ok(())
144 }
145 };
146 (int, $value:expr, $schema:expr, $span:expr) => {
147 if let Some(enum_vals) = &$schema.enum_values {
148 let mut errors = ErrorsInner::new();
149
150 let mut enum_contains = false;
151 for val in enum_vals {
152 if let Some(v) = val.as_i64() {
153 if v == $value as i64 {
154 enum_contains = true;
155 break;
156 }
157 }
158 if let Some(v) = val.as_u64() {
159 if v == $value as u64 {
160 enum_contains = true;
161 break;
162 }
163 }
164 }
165
166 if enum_contains {
167 Ok(())
168 } else {
169 errors.push(Error::new(
170 $schema.metadata.clone(),
171 $span.clone(),
172 ErrorValue::InvalidEnumValue {
173 expected: enum_vals.clone(),
174 },
175 ));
176 Err(Errors(errors))
177 }
178 } else {
179 Ok(())
180 }
181 };
182 (float, $value:expr, $schema:expr, $span:expr) => {
183 if let Some(enum_vals) = &$schema.enum_values {
184 let mut errors = ErrorsInner::new();
185
186 let mut enum_contains = false;
187 for val in enum_vals {
188 if let Some(v) = val.as_f64() {
189 if f64::abs(v - $value as f64) < core::f64::EPSILON {
190 enum_contains = true;
191 break;
192 }
193 }
194 }
195
196 if enum_contains {
197 Ok(())
198 } else {
199 errors.push(Error::new(
200 $schema.metadata.clone(),
201 $span.clone(),
202 ErrorValue::InvalidEnumValue {
203 expected: enum_vals.clone(),
204 },
205 ));
206 Err(Errors(errors))
207 }
208 } else {
209 Ok(())
210 }
211 };
212 (str, $value:expr, $schema:expr, $span:expr) => {
213 if let Some(enum_vals) = &$schema.enum_values {
214 let mut enum_contains = false;
215 for val in enum_vals {
216 if let Some(v) = val.as_str() {
217 if v == $value {
218 enum_contains = true;
219 break;
220 }
221 }
222 }
223
224 if enum_contains {
225 Ok(())
226 } else {
227 let mut errors = ErrorsInner::new();
228 errors.push(Error::new(
229 $schema.metadata.clone(),
230 $span.clone(),
231 ErrorValue::InvalidEnumValue {
232 expected: enum_vals.clone(),
233 },
234 ));
235 Err(Errors(errors))
236 }
237 } else {
238 Ok(())
239 }
240 };
241}
242
243macro_rules! check_number {
244 ($value:expr, $schema:expr, $span:expr) => {
245 if let Some(n) = &$schema.number {
246 let mut errors = ErrorsInner::new();
247
248 let mut number_err = false;
249
250 if let Some(m) = n.multiple_of {
251 if m != 0f64 && $value as f64 % m != 0f64 {
252 errors.push(Error::new(
253 $schema.metadata.clone(),
254 $span.clone(),
255 ErrorValue::NotMultipleOf { multiple_of: m },
256 ));
257 number_err = true;
258 }
259 }
260
261 if let Some(min) = n.minimum {
262 if ($value as f64) < min {
263 errors.push(Error::new(
264 $schema.metadata.clone(),
265 $span.clone(),
266 ErrorValue::LessThanExpected {
267 min,
268 exclusive: false,
269 },
270 ));
271 number_err = true;
272 }
273 }
274
275 if let Some(min) = n.exclusive_minimum {
276 if ($value as f64) <= min {
277 errors.push(Error::new(
278 $schema.metadata.clone(),
279 $span.clone(),
280 ErrorValue::LessThanExpected {
281 min,
282 exclusive: true,
283 },
284 ));
285 number_err = true;
286 }
287 }
288
289 if let Some(max) = n.maximum {
290 if ($value as f64) > max {
291 errors.push(Error::new(
292 $schema.metadata.clone(),
293 $span.clone(),
294 ErrorValue::MoreThanExpected {
295 max,
296 exclusive: false,
297 },
298 ));
299 number_err = true;
300 }
301 }
302
303 if let Some(max) = n.exclusive_maximum {
304 if ($value as f64) >= max {
305 errors.push(Error::new(
306 $schema.metadata.clone(),
307 $span.clone(),
308 ErrorValue::MoreThanExpected {
309 max,
310 exclusive: true,
311 },
312 ));
313 number_err = true;
314 }
315 }
316 if !number_err {
317 Ok(())
318 } else {
319 Err(Errors(errors))
320 }
321 } else {
322 Ok(())
323 };
324 };
325}
326
327macro_rules! check_string {
329 ($value:expr, $schema:expr, $span:expr) => {
330 if let Some(s) = &$schema.string {
331 let mut errors = ErrorsInner::new();
332
333 let mut string_err = false;
334
335 if let Some(p) = &s.pattern {
336 let re = regex::Regex::new(&*p).map_err(|error| {
337 Errors::one(Error::new(
338 $schema.metadata.clone(),
339 $span.clone(),
340 ErrorValue::InvalidSchema(InvalidSchema::InvalidPattern {
341 pattern: p.clone(),
342 error,
343 }),
344 ))
345 })?;
346
347 if !re.is_match($value) {
348 errors.push(Error::new(
349 $schema.metadata.clone(),
350 $span.clone(),
351 ErrorValue::NoPatternMatch { pattern: p.clone() },
352 ));
353 string_err = true;
354 }
355
356 if let Some(max_length) = s.max_length {
357 if $value.chars().count() > max_length as usize {
358 errors.push(Error::new(
359 $schema.metadata.clone(),
360 $span.clone(),
361 ErrorValue::TooLong { max_length },
362 ));
363 string_err = true;
364 }
365 }
366
367 if let Some(min_length) = s.min_length {
368 if $value.chars().count() < min_length as usize {
369 errors.push(Error::new(
370 $schema.metadata.clone(),
371 $span.clone(),
372 ErrorValue::TooShort { min_length },
373 ));
374 string_err = true;
375 }
376 }
377 }
378
379 if !string_err {
380 Ok(())
381 } else {
382 Err(Errors(errors))
383 }
384 } else {
385 Ok(())
386 }
387 };
388}