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