valico/json_schema/validators/
conditional.rs

1use serde_json::Value;
2use url;
3
4use super::super::scope;
5
6#[allow(missing_copy_implementations)]
7pub struct Conditional {
8    pub if_: url::Url,
9    pub then_: Option<url::Url>,
10    pub else_: Option<url::Url>,
11}
12
13impl super::Validator for Conditional {
14    fn validate(
15        &self,
16        val: &Value,
17        path: &str,
18        scope: &scope::Scope,
19        _: &super::ValidationState,
20    ) -> super::ValidationState {
21        let mut state = super::ValidationState::new();
22
23        let schema_if_ = scope.resolve(&self.if_);
24        if let Some(schema_if) = schema_if_ {
25            // TODO should the validation be strict?
26            let if_state = schema_if.validate_in(val, path);
27            if if_state.is_valid() {
28                state.evaluated.extend(if_state.evaluated);
29                if self.then_.is_some() {
30                    let schema_then_ = scope.resolve(self.then_.as_ref().unwrap());
31
32                    if let Some(schema_then) = schema_then_ {
33                        state.append(schema_then.validate_in(val, path));
34                    } else {
35                        state.missing.push(self.then_.as_ref().unwrap().clone());
36                    }
37                }
38            } else if self.else_.is_some() {
39                let schema_else_ = scope.resolve(self.else_.as_ref().unwrap());
40
41                if let Some(schema_else) = schema_else_ {
42                    state.append(schema_else.validate_in(val, path));
43                } else {
44                    state.missing.push(self.else_.as_ref().unwrap().clone());
45                }
46            }
47        } else {
48            state.missing.push(self.if_.clone());
49        }
50        state
51    }
52}