valico/json_schema/keywords/
maxmin_length.rs1use serde_json::Value;
2
3use super::super::schema;
4use super::super::validators;
5
6macro_rules! kw_minmax_integer {
7 ($name:ident, $keyword:expr) => {
8 #[allow(missing_copy_implementations)]
9 pub struct $name;
10 impl super::Keyword for $name {
11 fn compile(&self, def: &Value, ctx: &schema::WalkContext<'_>) -> super::KeywordResult {
12 let length = keyword_key_exists!(def, $keyword);
13
14 if length.is_number() {
15 let length_val = length.as_f64().unwrap();
16 if length_val >= 0f64 && length_val.fract() == 0f64 {
17 Ok(Some(Box::new(validators::$name {
18 length: length_val as u64,
19 })))
20 } else {
21 Err(schema::SchemaError::Malformed {
22 path: ctx.fragment.join("/"),
23 detail: "The value MUST be a positive integer or zero".to_string(),
24 })
25 }
26 } else {
27 Err(schema::SchemaError::Malformed {
28 path: ctx.fragment.join("/"),
29 detail: "The value MUST be a positive integer or zero".to_string(),
30 })
31 }
32 }
33 }
34 };
35}
36
37kw_minmax_integer!(MaxLength, "maxLength");
38kw_minmax_integer!(MinLength, "minLength");
39
40#[cfg(test)]
41use super::super::builder;
42#[cfg(test)]
43use super::super::scope;
44#[cfg(test)]
45use serde_json::to_value;
46
47#[test]
48fn validate_max_length() {
49 let mut scope = scope::Scope::new();
50 let schema = scope
51 .compile_and_return(
52 builder::schema(|s| {
53 s.max_length(5u64);
54 })
55 .into_json(),
56 true,
57 )
58 .ok()
59 .unwrap();
60
61 assert_eq!(schema.validate(&to_value("1234").unwrap()).is_valid(), true);
62 assert_eq!(
63 schema.validate(&to_value("12345").unwrap()).is_valid(),
64 true
65 );
66 assert_eq!(
67 schema.validate(&to_value("123456").unwrap()).is_valid(),
68 false
69 );
70}
71
72#[test]
73fn malformed_max_length() {
74 let mut scope = scope::Scope::new();
75
76 assert!(scope
77 .compile_and_return(
78 jsonway::object(|schema| {
79 schema.set("maxLength", to_value(-1).unwrap());
80 })
81 .unwrap(),
82 true
83 )
84 .is_err());
85
86 assert!(scope
87 .compile_and_return(
88 jsonway::object(|schema| {
89 schema.set("maxLength", to_value("").unwrap());
90 })
91 .unwrap(),
92 true
93 )
94 .is_err());
95
96 assert!(scope
97 .compile_and_return(
98 jsonway::object(|schema| {
99 schema.set("maxLength", to_value(1.1).unwrap());
100 })
101 .unwrap(),
102 true
103 )
104 .is_err());
105}
106
107#[test]
108fn validate_min_length() {
109 let mut scope = scope::Scope::new();
110 let schema = scope
111 .compile_and_return(
112 builder::schema(|s| {
113 s.min_length(5u64);
114 })
115 .into_json(),
116 true,
117 )
118 .ok()
119 .unwrap();
120
121 assert_eq!(
122 schema.validate(&to_value("1234").unwrap()).is_valid(),
123 false
124 );
125 assert_eq!(
126 schema.validate(&to_value("12345").unwrap()).is_valid(),
127 true
128 );
129 assert_eq!(
130 schema.validate(&to_value("123456").unwrap()).is_valid(),
131 true
132 );
133}
134
135#[test]
136fn malformed_min_length() {
137 let mut scope = scope::Scope::new();
138
139 assert!(scope
140 .compile_and_return(
141 jsonway::object(|schema| {
142 schema.set("minLength", to_value(-1).unwrap());
143 })
144 .unwrap(),
145 true
146 )
147 .is_err());
148
149 assert!(scope
150 .compile_and_return(
151 jsonway::object(|schema| {
152 schema.set("minLength", to_value("").unwrap());
153 })
154 .unwrap(),
155 true
156 )
157 .is_err());
158
159 assert!(scope
160 .compile_and_return(
161 jsonway::object(|schema| {
162 schema.set("minLength", to_value(1.1).unwrap());
163 })
164 .unwrap(),
165 true
166 )
167 .is_err());
168}