1use jsonway;
2use std::collections;
3use serde_json::value::{Value, to_value};
4use serde::{Serialize, Serializer};
5
6pub struct SchemaArray {
7 items: Vec<Value>
8}
9
10impl SchemaArray {
11 pub fn new() -> SchemaArray {
12 SchemaArray { items: vec![] }
13 }
14
15 pub fn push<F>(&mut self, build: F) where F: FnOnce(&mut Builder) {
16 self.items.push( Builder::build(build).into_json() )
17 }
18}
19
20pub struct SchemaHash {
21 items: collections::HashMap<String, Value>
22}
23
24impl SchemaHash {
25 pub fn new() -> SchemaHash {
26 SchemaHash { items: collections::HashMap::new() }
27 }
28
29 pub fn insert<F>(&mut self, key: &str, build: F) where F: FnOnce(&mut Builder) {
30 self.items.insert(key.to_string(), Builder::build(build).into_json());
31 }
32}
33
34pub struct Dependencies {
35 deps: collections::HashMap<String, Dependency>
36}
37
38impl Dependencies {
39 pub fn new() -> Dependencies {
40 Dependencies {
41 deps: collections::HashMap::new()
42 }
43 }
44
45 pub fn schema<F>(&mut self, property: &str, build: F) where F: FnOnce(&mut Builder) {
46 self.deps.insert(property.to_string(), Dependency::Schema( Builder::build(build).into_json() ));
47 }
48
49 pub fn property(&mut self, property: &str, properties: Vec<String>) {
50 self.deps.insert(property.to_string(), Dependency::Property(properties));
51 }
52
53 pub fn build<F>(build: F) -> Dependencies where F: FnOnce(&mut Dependencies) {
54 let mut deps = Dependencies::new();
55 build(&mut deps);
56 deps
57 }
58}
59
60impl Serialize for Dependencies {
61 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
62 self.deps.serialize(serializer)
63 }
64}
65
66pub enum Dependency {
67 Schema(Value),
68 Property(Vec<String>)
69}
70
71impl Serialize for Dependency {
72 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
73 match self {
74 &Dependency::Schema(ref json) => json.serialize(serializer),
75 &Dependency::Property(ref array) => array.serialize(serializer)
76 }
77 }
78}
79
80pub struct Builder {
84 obj_builder: jsonway::ObjectBuilder
85}
86
87impl Builder {
88 pub fn new() -> Builder {
89 Builder {
90 obj_builder: jsonway::ObjectBuilder::new()
91 }
92 }
93
94 pub fn id(&mut self, url: &str) {
95 self.obj_builder.set("id", url.to_string())
96 }
97
98 pub fn ref_(&mut self, url: &str) {
99 self.obj_builder.set("$ref", url.to_string())
100 }
101
102 pub fn schema(&mut self, url: &str) {
103 self.obj_builder.set("$schema", url.to_string())
104 }
105
106 pub fn desc(&mut self, text: &str) {
107 self.obj_builder.set("description", text.to_string())
108 }
109
110 pub fn title(&mut self, text: &str) {
111 self.obj_builder.set("title", text.to_string())
112 }
113
114 pub fn default<T>(&mut self, default: T) where T: Serialize {
115 self.obj_builder.set("default", default)
116 }
117
118 pub fn multiple_of(&mut self, number: f64) {
119 self.obj_builder.set("multipleOf", number)
120 }
121
122 pub fn maximum(&mut self, number: f64, exclusive: bool) {
123 self.obj_builder.set("maximum", number);
124 if exclusive {
125 self.obj_builder.set("exclusiveMaximum", exclusive)
126 }
127 }
128
129 pub fn minimum(&mut self, number: f64, exclusive: bool) {
130 self.obj_builder.set("minimum", number);
131 if exclusive {
132 self.obj_builder.set("exclusiveMinimum", exclusive)
133 }
134 }
135
136 pub fn max_length(&mut self, number: u64) {
137 self.obj_builder.set("maxLength", number)
138 }
139
140 pub fn min_length(&mut self, number: u64) {
141 self.obj_builder.set("minLength", number)
142 }
143
144 pub fn pattern(&mut self, pattern: &str) {
145 self.obj_builder.set("pattern", pattern.to_string())
146 }
147
148 pub fn format(&mut self, format: &str) {
149 self.obj_builder.set("format", format.to_string())
150 }
151
152 pub fn items_schema<F>(&mut self, build: F) where F: FnOnce(&mut Builder) {
153 self.obj_builder.set("items", Builder::build(build).into_json() )
154 }
155
156 pub fn items_array<F>(&mut self, build: F) where F: FnOnce(&mut SchemaArray) {
157 let mut items = SchemaArray::new();
158 build(&mut items);
159 self.obj_builder.set("items", items.items)
160 }
161
162 pub fn additional_items(&mut self, allow: bool) {
163 self.obj_builder.set("additionalItems", allow)
164 }
165
166 pub fn additional_items_schema<F>(&mut self, build: F) where F: FnOnce(&mut Builder) {
167 self.obj_builder.set("additionalItems", Builder::build(build).into_json())
168 }
169
170 pub fn max_items(&mut self, number: u64) {
171 self.obj_builder.set("maxItems", number)
172 }
173
174 pub fn min_items(&mut self, number: u64) {
175 self.obj_builder.set("minItems", number)
176 }
177
178 pub fn unique_items(&mut self, unique: bool) {
179 self.obj_builder.set("uniqueItems", unique)
180 }
181
182 pub fn max_properties(&mut self, number: u64) {
183 self.obj_builder.set("maxProperties", number)
184 }
185
186 pub fn min_properties(&mut self, number: u64) {
187 self.obj_builder.set("minProperties", number)
188 }
189
190 pub fn required(&mut self, items: Vec<String>) {
191 self.obj_builder.set("required", items)
192 }
193
194 pub fn properties<F>(&mut self, build: F) where F: FnOnce(&mut SchemaHash) {
195 let mut items = SchemaHash::new();
196 build(&mut items);
197 self.obj_builder.set("properties", items.items)
198 }
199
200 pub fn pattern_properties<F>(&mut self, build: F) where F: FnOnce(&mut SchemaHash) {
201 let mut items = SchemaHash::new();
202 build(&mut items);
203 self.obj_builder.set("patternProperties", items.items)
204 }
205
206 pub fn additional_properties(&mut self, allow: bool) {
207 self.obj_builder.set("additionalProperties", allow)
208 }
209
210 pub fn additional_properties_schema<F>(&mut self, build: F) where F: FnOnce(&mut Builder) {
211 self.obj_builder.set("additionalProperties", Builder::build(build).into_json())
212 }
213
214 pub fn dependencies<F>(&mut self, build: F) where F: FnOnce(&mut Dependencies) {
215 self.obj_builder.set("dependencies", Dependencies::build(build))
216 }
217
218 pub fn enum_<F>(&mut self, build: F) where F: FnOnce(&mut jsonway::ArrayBuilder) {
219 self.obj_builder.set("enum", jsonway::array(build).unwrap())
220 }
221
222 pub fn array(&mut self) {
223 self.obj_builder.set("type", super::PrimitiveType::Array.to_string())
224 }
225 pub fn boolean(&mut self) {
226 self.obj_builder.set("type", super::PrimitiveType::Boolean.to_string())
227 }
228 pub fn integer(&mut self) {
229 self.obj_builder.set("type", super::PrimitiveType::Integer.to_string())
230 }
231 pub fn number(&mut self) {
232 self.obj_builder.set("type", super::PrimitiveType::Number.to_string())
233 }
234 pub fn null(&mut self) {
235 self.obj_builder.set("type", super::PrimitiveType::Null.to_string())
236 }
237 pub fn object(&mut self) {
238 self.obj_builder.set("type", super::PrimitiveType::Object.to_string())
239 }
240 pub fn string(&mut self) {
241 self.obj_builder.set("type", super::PrimitiveType::String.to_string())
242 }
243 pub fn type_(&mut self, type_: super::PrimitiveType) {
244 self.obj_builder.set("type", type_.to_string())
245 }
246 pub fn types(&mut self, types: &[super::PrimitiveType]) {
247 self.obj_builder.set("type", to_value(&types.iter().map(|t| t.to_string()).collect::<Vec<String>>()).unwrap())
248 }
249
250 pub fn all_of<F>(&mut self, build: F) where F: FnOnce(&mut SchemaArray) {
251 let mut items = SchemaArray::new();
252 build(&mut items);
253 self.obj_builder.set("allOf", items.items)
254 }
255
256 pub fn any_of<F>(&mut self, build: F) where F: FnOnce(&mut SchemaArray) {
257 let mut items = SchemaArray::new();
258 build(&mut items);
259 self.obj_builder.set("anyOf", items.items)
260 }
261
262 pub fn one_of<F>(&mut self, build: F) where F: FnOnce(&mut SchemaArray) {
263 let mut items = SchemaArray::new();
264 build(&mut items);
265 self.obj_builder.set("oneOf", items.items)
266 }
267
268 pub fn not<F>(&mut self, build: F) where F: FnOnce(&mut Builder) {
269 self.obj_builder.set("not", Builder::build(build).into_json())
270 }
271
272 pub fn build<F>(build: F) -> Builder where F: FnOnce(&mut Builder) {
273 let mut builder = Builder::new();
274 build(&mut builder);
275 builder
276 }
277
278 pub fn into_json(self) -> Value {
279 self.obj_builder.unwrap()
280 }
281}
282
283impl Serialize for Builder {
284 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
285 self.obj_builder.serialize(serializer)
286 }
287}
288
289pub fn schema<F>(build: F) -> Builder where F: FnOnce(&mut Builder) {
290 Builder::build(build)
291}
292
293pub fn schema_box(build: Box<Fn(&mut Builder) + Send>) -> Builder {
294 let mut builder = Builder::new();
295 build(&mut builder);
296 builder
297}