valico/json_schema/keywords/
pattern.rs1use serde_json::Value;
2
3use super::super::schema;
4use super::super::validators;
5
6#[allow(missing_copy_implementations)]
7pub struct Pattern;
8impl super::Keyword for Pattern {
9 fn compile(&self, def: &Value, ctx: &schema::WalkContext<'_>) -> super::KeywordResult {
10 let pattern = keyword_key_exists!(def, "pattern");
11
12 if pattern.is_string() {
13 let pattern_val = pattern.as_str().unwrap();
14 match fancy_regex::Regex::new(pattern_val) {
15 Ok(re) => Ok(Some(Box::new(validators::Pattern { regex: re }))),
16 Err(err) => Err(schema::SchemaError::Malformed {
17 path: ctx.fragment.join("/"),
18 detail: format!("The value of pattern MUST be a valid RegExp, but {err:?}"),
19 }),
20 }
21 } else {
22 Err(schema::SchemaError::Malformed {
23 path: ctx.fragment.join("/"),
24 detail: "The value of pattern MUST be a string".to_string(),
25 })
26 }
27 }
28}
29
30#[cfg(test)]
31use super::super::builder;
32#[cfg(test)]
33use super::super::scope;
34#[cfg(test)]
35use serde_json::to_value;
36
37#[test]
38fn validate() {
39 let mut scope = scope::Scope::new();
40 let schema = scope
41 .compile_and_return(
42 builder::schema(|s| {
43 s.pattern(r"abb.*");
44 })
45 .into_json(),
46 true,
47 )
48 .ok()
49 .unwrap();
50
51 assert_eq!(schema.validate(&to_value("abb").unwrap()).is_valid(), true);
52 assert_eq!(schema.validate(&to_value("abbd").unwrap()).is_valid(), true);
53 assert_eq!(schema.validate(&to_value("abd").unwrap()).is_valid(), false);
54}
55
56#[test]
57fn mailformed() {
58 let mut scope = scope::Scope::new();
59
60 assert!(scope
61 .compile_and_return(
62 jsonway::object(|schema| {
63 schema.set("pattern", "([]".to_string());
64 })
65 .unwrap(),
66 true
67 )
68 .is_err());
69
70 assert!(scope
71 .compile_and_return(
72 jsonway::object(|schema| {
73 schema.set("pattern", 2);
74 })
75 .unwrap(),
76 true
77 )
78 .is_err());
79}