1mod asset;
18mod compile;
19mod ctx;
20mod error;
21mod markdown;
22mod modifiers;
23mod primitives;
24
25pub use asset::*;
26pub use compile::compile_descriptor;
27pub use ctx::{AssetPipeline, Ctx};
28pub use error::ValidationError;
29pub use markdown::*;
30pub use modifiers::*;
31pub use primitives::*;
32
33use serde_json::Value;
34
35pub trait Schema: Send + Sync {
36 fn parse(&self, value: &Value, ctx: &Ctx) -> Result<Value, ValidationError>;
37}
38
39pub mod s {
40 use super::*;
41
42 pub fn string() -> StringSchema {
43 StringSchema::default()
44 }
45 pub fn number() -> NumberSchema {
46 NumberSchema::default()
47 }
48 pub fn boolean() -> BooleanSchema {
49 BooleanSchema
50 }
51 pub fn array(item: Box<dyn Schema>) -> ArraySchema {
52 ArraySchema { item, min: None, max: None }
53 }
54 pub fn object(fields: Vec<(String, Box<dyn Schema>)>) -> ObjectSchema {
55 ObjectSchema { fields, passthrough: false }
56 }
57 pub fn enum_(variants: Vec<Value>) -> EnumSchema {
58 EnumSchema { variants }
59 }
60 pub fn literal(expected: Value) -> LiteralSchema {
61 LiteralSchema { expected }
62 }
63 pub fn union(variants: Vec<Box<dyn Schema>>) -> UnionSchema {
64 UnionSchema { variants }
65 }
66 pub fn record(value: Box<dyn Schema>) -> RecordSchema {
67 RecordSchema { value }
68 }
69 pub fn tuple(items: Vec<Box<dyn Schema>>) -> TupleSchema {
70 TupleSchema { items }
71 }
72 pub fn intersection(left: Box<dyn Schema>, right: Box<dyn Schema>) -> IntersectionSchema {
73 IntersectionSchema { left, right }
74 }
75 pub fn discriminated_union(
76 discriminator: impl Into<String>,
77 variants: Vec<Box<dyn Schema>>,
78 ) -> DiscriminatedUnionSchema {
79 DiscriminatedUnionSchema { discriminator: discriminator.into(), variants }
80 }
81 pub fn coerce_string() -> CoerceSchema {
82 CoerceSchema { target: CoerceTarget::String }
83 }
84 pub fn coerce_number() -> CoerceSchema {
85 CoerceSchema { target: CoerceTarget::Number }
86 }
87 pub fn coerce_boolean() -> CoerceSchema {
88 CoerceSchema { target: CoerceTarget::Boolean }
89 }
90 pub fn coerce_date() -> CoerceSchema {
91 CoerceSchema { target: CoerceTarget::Date }
92 }
93
94 pub fn optional(inner: Box<dyn Schema>) -> OptionalSchema {
95 OptionalSchema { inner }
96 }
97 pub fn nullable(inner: Box<dyn Schema>) -> NullableSchema {
98 NullableSchema { inner }
99 }
100 pub fn default_(inner: Box<dyn Schema>, fallback: Value) -> DefaultSchema {
101 DefaultSchema { inner, fallback }
102 }
103 pub fn transform<F>(inner: Box<dyn Schema>, func: F) -> TransformSchema
104 where
105 F: Fn(Value) -> Value + Send + Sync + 'static,
106 {
107 TransformSchema { inner, func: Box::new(func) }
108 }
109 pub fn refine<F>(inner: Box<dyn Schema>, predicate: F) -> RefineSchema
110 where
111 F: Fn(&Value) -> Result<(), String> + Send + Sync + 'static,
112 {
113 RefineSchema { inner, predicate: Box::new(predicate) }
114 }
115 pub fn super_refine<F>(inner: Box<dyn Schema>, predicate: F) -> SuperRefineSchema
116 where
117 F: Fn(&Value, &mut Vec<String>) + Send + Sync + 'static,
118 {
119 SuperRefineSchema { inner, predicate: Box::new(predicate) }
120 }
121
122 pub fn raw() -> RawSchema {
123 RawSchema
124 }
125 pub fn markdown() -> MarkdownSchema {
126 MarkdownSchema
127 }
128 pub fn mdx() -> MdxSchema {
129 MdxSchema
130 }
131 pub fn toc() -> TocSchema {
132 TocSchema
133 }
134 pub fn metadata() -> MetadataSchema {
135 MetadataSchema
136 }
137 pub fn excerpt() -> ExcerptSchema {
138 ExcerptSchema::default()
139 }
140 pub fn path() -> PathSchema {
141 PathSchema::default()
142 }
143 pub fn slug() -> SlugSchema {
144 SlugSchema::default()
145 }
146 pub fn unique() -> UniqueSchema {
147 UniqueSchema::default()
148 }
149 pub fn isodate() -> IsodateSchema {
150 IsodateSchema
151 }
152 pub fn file() -> FileSchema {
153 FileSchema::default()
154 }
155 pub fn image() -> ImageSchema {
156 ImageSchema::default()
157 }
158}
159
160pub trait BoxSchema: Schema + Sized + 'static {
161 fn boxed(self) -> Box<dyn Schema> {
162 Box::new(self)
163 }
164}
165impl<T: Schema + Sized + 'static> BoxSchema for T {}