valico/json_schema/keywords/
of.rs
1use serde_json::{Value};
2
3use super::super::schema;
4use super::super::validators;
5use super::super::helpers;
6
7macro_rules! of_keyword{
8 ($name:ident, $kw:expr) => {
9
10 #[allow(missing_copy_implementations)]
11 pub struct $name;
12 impl super::Keyword for $name {
13 fn compile(&self, def: &Value, ctx: &schema::WalkContext) -> super::KeywordResult {
14 let of = keyword_key_exists!(def, $kw);
15
16 if of.is_array() {
17 let of = of.as_array().unwrap();
18
19 if of.len() == 0 {
20 return Err(schema::SchemaError::Malformed {
21 path: ctx.fragment.join("/"),
22 detail: "This array MUST have at least one element.".to_string()
23 })
24 }
25
26 let mut schemes = vec![];
27 for (idx, scheme) in of.iter().enumerate() {
28 if scheme.is_object() {
29 schemes.push(
30 helpers::alter_fragment_path(ctx.url.clone(), [
31 ctx.escaped_fragment().as_ref(),
32 $kw,
33 idx.to_string().as_ref()
34 ].join("/"))
35 )
36 } else {
37 return Err(schema::SchemaError::Malformed {
38 path: ctx.fragment.join("/"),
39 detail: "Elements of the array MUST be objects.".to_string()
40 })
41 }
42 }
43
44 Ok(Some(Box::new(validators::$name {
45 schemes: schemes
46 })))
47 } else {
48 Err(schema::SchemaError::Malformed {
49 path: ctx.fragment.join("/"),
50 detail: "The value of this keyword MUST be an array.".to_string()
51 })
52 }
53 }
54 }
55
56 }
57}
58
59of_keyword!(AllOf, "allOf");
60of_keyword!(AnyOf, "anyOf");
61of_keyword!(OneOf, "oneOf");
62
63#[cfg(test)] use super::super::scope;
64#[cfg(test)] use super::super::builder;
65#[cfg(test)] use serde_json::to_value;
66
67#[test]
68fn validate_all_of() {
69 let mut scope = scope::Scope::new();
70 let schema = scope.compile_and_return(builder::schema(|s| {
71 s.all_of(|all_of| {
72 all_of.push(|schema| {
73 schema.minimum(5f64, false);
74 });
75 all_of.push(|schema| {
76 schema.maximum(10f64, false);
77 });
78 });
79 }).into_json(), true).ok().unwrap();
80
81 assert_eq!(schema.validate(&to_value(&7).unwrap()).is_valid(), true);
82 assert_eq!(schema.validate(&to_value(&4).unwrap()).is_valid(), false);
83 assert_eq!(schema.validate(&to_value(&11).unwrap()).is_valid(), false);
84}
85
86#[test]
87fn validate_any_of() {
88 let mut scope = scope::Scope::new();
89 let schema = scope.compile_and_return(builder::schema(|s| {
90 s.any_of(|all_of| {
91 all_of.push(|schema| {
92 schema.maximum(5f64, false);
93 });
94 all_of.push(|schema| {
95 schema.maximum(10f64, false);
96 });
97 });
98 }).into_json(), true).ok().unwrap();
99
100 assert_eq!(schema.validate(&to_value(&5).unwrap()).is_valid(), true);
101 assert_eq!(schema.validate(&to_value(&10).unwrap()).is_valid(), true);
102 assert_eq!(schema.validate(&to_value(&11).unwrap()).is_valid(), false);
103}
104
105#[test]
106fn validate_one_of() {
107 let mut scope = scope::Scope::new();
108 let schema = scope.compile_and_return(builder::schema(|s| {
109 s.one_of(|all_of| {
110 all_of.push(|schema| {
111 schema.maximum(5f64, false);
112 });
113 all_of.push(|schema| {
114 schema.maximum(10f64, false);
115 });
116 });
117 }).into_json(), true).ok().unwrap();
118
119 assert_eq!(schema.validate(&to_value(&5).unwrap()).is_valid(), false);
120 assert_eq!(schema.validate(&to_value(&6).unwrap()).is_valid(), true);
121 assert_eq!(schema.validate(&to_value(&11).unwrap()).is_valid(), false);
122}