valico/json_schema/validators/
mod.rs

1use serde_json::{Value, to_value};
2use serde::{Serialize, Serializer};
3use std::fmt;
4use url;
5
6use super::scope;
7
8#[macro_export]
9macro_rules! strict_process {
10    ($val:expr, $path:ident, $err:expr) => {{
11        let maybe_val = $val;
12        if maybe_val.is_none() {
13            return val_error!(
14                $crate::json_schema::errors::WrongType {
15                    path: $path.to_string(),
16                    detail: $err.to_string()
17                }
18            )
19        }
20
21        maybe_val.unwrap()
22    }}
23}
24
25macro_rules! nonstrict_process {
26    ($val:expr, $path:ident) => {{
27        let maybe_val = $val;
28        if maybe_val.is_none() {
29            return $crate::json_schema::validators::ValidationState::new()
30        }
31
32        maybe_val.unwrap()
33    }}
34}
35
36macro_rules! val_error{
37    ($err:expr) => (
38        $crate::json_schema::validators::ValidationState{
39            errors: vec![
40                Box::new($err)
41            ],
42            missing: vec![]
43        }
44    )
45}
46
47pub use self::multiple_of::{MultipleOf};
48pub use self::maxmin::{Maximum, Minimum};
49pub use self::maxmin_length::{MaxLength, MinLength};
50pub use self::pattern::{Pattern};
51pub use self::maxmin_items::{MaxItems, MinItems};
52pub use self::unique_items::{UniqueItems};
53pub use self::items::{Items};
54pub use self::maxmin_properties::{MaxProperties, MinProperties};
55pub use self::required::{Required};
56pub use self::properties::{Properties};
57pub use self::dependencies::{Dependencies};
58pub use self::enum_::{Enum};
59pub use self::type_::{Type};
60pub use self::of::{AllOf, AnyOf, OneOf};
61pub use self::ref_::{Ref};
62pub use self::not::{Not};
63
64mod multiple_of;
65mod maxmin;
66mod maxmin_length;
67mod pattern;
68mod maxmin_items;
69mod unique_items;
70pub mod items;
71mod maxmin_properties;
72mod required;
73pub mod properties;
74pub mod dependencies;
75mod enum_;
76pub mod type_;
77mod of;
78mod ref_;
79mod not;
80pub mod formats;
81
82#[derive(Debug)]
83pub struct ValidationState {
84    pub errors: super::super::common::error::ValicoErrors,
85    pub missing: Vec<url::Url>
86}
87
88impl ValidationState {
89    pub fn new() -> ValidationState {
90        ValidationState {
91            errors: vec![],
92            missing: vec![]
93        }
94    }
95
96    pub fn is_valid(&self) -> bool {
97        self.errors.len() == 0
98    }
99
100    pub fn is_strictly_valid(&self) -> bool {
101        self.errors.len() == 0 && self.missing.len() == 0
102    }
103
104    pub fn append(&mut self, second: ValidationState) {
105        self.errors.extend(second.errors);
106        self.missing.extend(second.missing);
107    }
108}
109
110impl Serialize for ValidationState {
111    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
112        let mut map = ::serde_json::Map::new();
113        map.insert("errors".to_string(), Value::Array(
114            self.errors.iter().map(|err| to_value(err).unwrap()).collect::<Vec<Value>>()
115        ));
116        map.insert("missing".to_string(), Value::Array(
117            self.missing.iter().map(|url| to_value(&url.to_string()).unwrap()).collect::<Vec<Value>>()
118        ));
119        Value::Object(map).serialize(serializer)
120    }
121}
122
123pub trait Validator {
124    fn validate(&self, item: &Value, &str, &scope::Scope) -> ValidationState;
125}
126
127impl fmt::Debug for Validator + 'static + Send + Sync {
128    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
129        fmt.write_str("<validator>")
130    }
131}
132
133pub type BoxedValidator = Box<Validator + 'static + Send + Sync>;
134pub type Validators = Vec<BoxedValidator>;
135
136impl<T> Validator for T where T: Fn(&Value, &str, &scope::Scope) -> ValidationState {
137    fn validate(&self, val: &Value, path: &str, scope: &scope::Scope) -> ValidationState {
138        self(val, path, scope)
139    }
140}