Skip to main content

valico/json_schema/validators/
dependencies.rs

1use serde_json::Value;
2use std::borrow::Cow;
3
4use super::super::errors;
5use super::super::scope;
6
7#[derive(Debug)]
8pub enum DepKind {
9    Schema(url::Url),
10    Property(Vec<String>),
11}
12
13#[allow(missing_copy_implementations)]
14pub struct Dependencies {
15    pub items: Vec<(String, DepKind)>,
16}
17
18impl super::Validator for Dependencies {
19    fn validate(
20        &self,
21        val: &Value,
22        path: &str,
23        scope: &scope::Scope,
24        _: &super::ValidationState,
25    ) -> super::ValidationState {
26        let mut state = super::ValidationState::new();
27        if !val.is_object() {
28            return state;
29        }
30        let mut object = Cow::Borrowed(val);
31
32        for (key, dep) in self.items.iter() {
33            if object.get(key).is_some() {
34                match dep {
35                    DepKind::Schema(ref url) => {
36                        let schema = scope.resolve(url);
37                        if let Some(schema) = schema {
38                            let mut result = schema.validate_in(&object, path);
39                            if result.is_valid() && result.replacement.is_some() {
40                                *object.to_mut() = result.replacement.take().unwrap();
41                            }
42                            state.append(result);
43                        } else {
44                            state.missing.push(url.clone())
45                        }
46                    }
47                    DepKind::Property(ref keys) => {
48                        for key in keys.iter() {
49                            if object.get(key).is_none() {
50                                state.errors.push(Box::new(errors::Required {
51                                    path: [path, key.as_ref()].join("/"),
52                                }))
53                            }
54                        }
55                    }
56                }
57            }
58        }
59
60        state.set_replacement(object);
61        state
62    }
63}