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}