Skip to main content

dmc_schema/
modifiers.rs

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
47/// `Ok(())` passes; `Err(msg)` surfaces a single root-level error.
48pub type RefinePredicate = Box<dyn Fn(&Value) -> Result<(), String> + Send + Sync>;
49
50/// Pushes zero or more errors into the caller-provided buffer.
51pub 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}