Skip to main content

vld/combinators/
lazy_schema.rs

1use serde_json::Value;
2use std::marker::PhantomData;
3
4use crate::error::VldError;
5use crate::schema::VldSchema;
6
7/// Lazy schema for recursive/self-referencing data structures.
8///
9/// The schema factory is called on each `parse_value` invocation,
10/// which allows defining schemas that reference themselves.
11///
12/// Created via [`vld::lazy()`](crate::lazy).
13///
14/// # Example
15/// ```ignore
16/// // Recursive tree: { value: i64, children: Tree[] }
17/// fn tree_schema() -> impl VldSchema<Output = serde_json::Value> {
18///     vld::object()
19///         .field("value", vld::number().int())
20///         .field("children", vld::array(vld::lazy(tree_schema)))
21/// }
22/// ```
23pub struct ZLazy<T, F>
24where
25    F: Fn() -> T,
26    T: VldSchema,
27{
28    factory: F,
29    _phantom: PhantomData<T>,
30}
31
32impl<T, F> ZLazy<T, F>
33where
34    F: Fn() -> T,
35    T: VldSchema,
36{
37    pub fn new(factory: F) -> Self {
38        Self {
39            factory,
40            _phantom: PhantomData,
41        }
42    }
43}
44
45impl<T, F> VldSchema for ZLazy<T, F>
46where
47    F: Fn() -> T,
48    T: VldSchema,
49{
50    type Output = T::Output;
51
52    fn parse_value(&self, value: &Value) -> Result<T::Output, VldError> {
53        let schema = (self.factory)();
54        schema.parse_value(value)
55    }
56}