valico/json_schema/keywords/
maxmin_length.rs

1use 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}