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}