valico/json_schema/keywords/
mod.rs
1use serde_json::{Value};
2use std::fmt;
3use std::rc;
4use std::collections;
5use std::any;
6
7use super::schema;
8use super::validators;
9
10pub type KeywordResult = Result<Option<validators::BoxedValidator>, schema::SchemaError>;
11pub type KeywordPair = (Vec<&'static str>, Box<Keyword + 'static>);
12pub type KeywordPairs = Vec<KeywordPair>;
13pub type KeywordMap = collections::HashMap<&'static str, rc::Rc<KeywordConsumer>>;
14
15pub trait Keyword: Sync + any::Any {
16 fn compile(&self, &Value, &schema::WalkContext) -> KeywordResult;
17
18 fn is_exclusive(&self) -> bool {
19 false
20 }
21}
22
23impl<T: 'static + Send + Sync + any::Any> Keyword for T where T: Fn(&Value, &schema::WalkContext) -> KeywordResult {
24 fn compile(&self, def: &Value, ctx: &schema::WalkContext) -> KeywordResult {
25 self(def, ctx)
26 }
27}
28
29impl fmt::Debug for Keyword + 'static {
30 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
31 fmt.write_str("<keyword>")
32 }
33}
34
35macro_rules! keyword_key_exists {
36 ($val:expr, $key:expr) => {{
37 let maybe_val = $val.get($key);
38 if maybe_val.is_none() {
39 return Ok(None)
40 } else {
41 maybe_val.unwrap()
42 }
43 }}
44}
45
46pub mod multiple_of;
47pub mod maxmin;
48#[macro_use]
49pub mod maxmin_length;
50pub mod maxmin_items;
51pub mod pattern;
52pub mod unique_items;
53pub mod items;
54pub mod maxmin_properties;
55pub mod required;
56pub mod properties;
57pub mod dependencies;
58pub mod enum_;
59pub mod type_;
60pub mod of;
61pub mod ref_;
62pub mod not;
63pub mod format;
64
65pub fn default() -> KeywordMap {
66 let mut map = collections::HashMap::new();
67
68 decouple_keyword((vec!["multipleOf"], Box::new(multiple_of::MultipleOf)), &mut map);
69 decouple_keyword((vec!["maximum", "exclusiveMaximum"], Box::new(maxmin::Maximum)), &mut map);
70 decouple_keyword((vec!["minimum", "exclusiveMinimum"], Box::new(maxmin::Minimum)), &mut map);
71 decouple_keyword((vec!["maxLength"], Box::new(maxmin_length::MaxLength)), &mut map);
72 decouple_keyword((vec!["minLength"], Box::new(maxmin_length::MinLength)), &mut map);
73 decouple_keyword((vec!["pattern"], Box::new(pattern::Pattern)), &mut map);
74 decouple_keyword((vec!["maxItems"], Box::new(maxmin_items::MaxItems)), &mut map);
75 decouple_keyword((vec!["minItems"], Box::new(maxmin_items::MinItems)), &mut map);
76 decouple_keyword((vec!["uniqueItems"], Box::new(unique_items::UniqueItems)), &mut map);
77 decouple_keyword((vec!["items", "additionalItems"], Box::new(items::Items)), &mut map);
78 decouple_keyword((vec!["maxProperties"], Box::new(maxmin_properties::MaxProperties)), &mut map);
79 decouple_keyword((vec!["minProperties"], Box::new(maxmin_properties::MinProperties)), &mut map);
80 decouple_keyword((vec!["required"], Box::new(required::Required)), &mut map);
81 decouple_keyword((vec!["properties", "additionalProperties", "patternProperties"], Box::new(properties::Properties)), &mut map);
82 decouple_keyword((vec!["dependencies"], Box::new(dependencies::Dependencies)), &mut map);
83 decouple_keyword((vec!["enum"], Box::new(enum_::Enum)), &mut map);
84 decouple_keyword((vec!["type"], Box::new(type_::Type)), &mut map);
85 decouple_keyword((vec!["allOf"], Box::new(of::AllOf)), &mut map);
86 decouple_keyword((vec!["anyOf"], Box::new(of::AnyOf)), &mut map);
87 decouple_keyword((vec!["oneOf"], Box::new(of::OneOf)), &mut map);
88 decouple_keyword((vec!["$ref"], Box::new(ref_::Ref)), &mut map);
89 decouple_keyword((vec!["not"], Box::new(not::Not)), &mut map);
90
91 map
92}
93
94#[derive(Debug)]
95pub struct KeywordConsumer {
96 pub keys: Vec<&'static str>,
97 pub keyword: Box<Keyword + 'static>
98}
99
100impl KeywordConsumer {
101 pub fn consume(&self, set: &mut collections::HashSet<&str>) {
102 for key in self.keys.iter() {
103 if set.contains(key) {
104 set.remove(key);
105 }
106 }
107 }
108}
109
110pub fn decouple_keyword(keyword_pair: KeywordPair,
111 map: &mut KeywordMap) {
112 let (keys, keyword) = keyword_pair;
113 let consumer = rc::Rc::new(KeywordConsumer { keys: keys.clone(), keyword: keyword });
114 for key in keys.iter() {
115 map.insert(key, consumer.clone());
116 }
117}