1use crate::{Ctx, Schema, ValidationError};
2use serde_json::Value;
3
4pub struct OptionalSchema {
5 pub inner: Box<dyn Schema>,
6}
7
8impl Schema for OptionalSchema {
9 fn parse(&self, value: &Value, ctx: &Ctx) -> Result<Value, ValidationError> {
10 if value.is_null() { Ok(Value::Null) } else { self.inner.parse(value, ctx) }
11 }
12}
13
14pub struct NullableSchema {
15 pub inner: Box<dyn Schema>,
16}
17
18impl Schema for NullableSchema {
19 fn parse(&self, value: &Value, ctx: &Ctx) -> Result<Value, ValidationError> {
20 if value.is_null() { Ok(Value::Null) } else { self.inner.parse(value, ctx) }
21 }
22}
23
24pub struct DefaultSchema {
25 pub inner: Box<dyn Schema>,
26 pub fallback: Value,
27}
28
29impl Schema for DefaultSchema {
30 fn parse(&self, value: &Value, ctx: &Ctx) -> Result<Value, ValidationError> {
31 if value.is_null() { self.inner.parse(&self.fallback, ctx) } else { self.inner.parse(value, ctx) }
32 }
33}
34
35pub struct TransformSchema {
36 pub inner: Box<dyn Schema>,
37 pub func: Box<dyn Fn(Value) -> Value + Send + Sync>,
38}
39
40impl Schema for TransformSchema {
41 fn parse(&self, value: &Value, ctx: &Ctx) -> Result<Value, ValidationError> {
42 let parsed = self.inner.parse(value, ctx)?;
43 Ok((self.func)(parsed))
44 }
45}
46
47pub type RefinePredicate = Box<dyn Fn(&Value) -> Result<(), String> + Send + Sync>;
49
50pub type SuperRefinePredicate = Box<dyn Fn(&Value, &mut Vec<String>) + Send + Sync>;
52
53pub struct RefineSchema {
54 pub inner: Box<dyn Schema>,
55 pub predicate: RefinePredicate,
56}
57
58impl Schema for RefineSchema {
59 fn parse(&self, value: &Value, ctx: &Ctx) -> Result<Value, ValidationError> {
60 let parsed = self.inner.parse(value, ctx)?;
61 (self.predicate)(&parsed).map_err(ValidationError::root)?;
62 Ok(parsed)
63 }
64}
65
66pub struct SuperRefineSchema {
67 pub inner: Box<dyn Schema>,
68 pub predicate: SuperRefinePredicate,
69}
70
71impl Schema for SuperRefineSchema {
72 fn parse(&self, value: &Value, ctx: &Ctx) -> Result<Value, ValidationError> {
73 let parsed = self.inner.parse(value, ctx)?;
74 let mut errors = Vec::new();
75 (self.predicate)(&parsed, &mut errors);
76 if !errors.is_empty() {
77 return Err(ValidationError::root(errors.join("; ")));
78 }
79 Ok(parsed)
80 }
81}