yaml_schema/validation/
context.rs1use std::cell::RefCell;
2use std::collections::HashSet;
3use std::rc::Rc;
4
5use crate::RootSchema;
6use crate::YamlSchema;
7use crate::validation::ValidationError;
8
9#[derive(Debug, Default)]
11pub struct Context<'r> {
12 pub root_schema: Option<&'r RootSchema<'r>>,
14 pub current_schema: Option<&'r YamlSchema<'r>>,
15 pub current_path: Vec<String>,
16 pub stream_started: bool,
17 pub stream_ended: bool,
18 pub errors: Rc<RefCell<Vec<ValidationError>>>,
19 pub fail_fast: bool,
20 pub resolving_refs: Rc<RefCell<HashSet<(String, usize)>>>,
25}
26
27impl<'r> Context<'r> {
28 pub fn has_errors(&self) -> bool {
30 !self.errors.borrow().is_empty()
31 }
32
33 pub fn path(&self) -> String {
35 self.current_path.join(".")
36 }
37
38 pub fn new(fail_fast: bool) -> Context<'r> {
39 Context {
40 fail_fast,
41 ..Default::default()
42 }
43 }
44
45 pub fn get_sub_context(&self) -> Context<'r> {
46 Context {
47 root_schema: self.root_schema,
48 current_schema: self.current_schema,
49 current_path: self.current_path.clone(),
50 stream_started: self.stream_started,
51 stream_ended: self.stream_ended,
52 errors: Rc::new(RefCell::new(Vec::new())),
53 fail_fast: self.fail_fast,
54 resolving_refs: self.resolving_refs.clone(),
55 }
56 }
57
58 pub fn with_root_schema(root_schema: &'r RootSchema, fail_fast: bool) -> Context<'r> {
59 Context {
60 root_schema: Some(root_schema),
61 fail_fast,
62 ..Default::default()
63 }
64 }
65
66 fn push_error(&self, error: ValidationError) {
67 self.errors.borrow_mut().push(error);
68 }
69
70 pub fn add_doc_error<V: Into<String>>(&self, error: V) {
71 let path = self.path();
72 self.push_error(ValidationError {
73 path,
74 marker: None,
75 error: error.into(),
76 });
77 }
78
79 pub fn add_error<V: Into<String>>(&self, marked_yaml: &saphyr::MarkedYaml, error: V) {
81 let path = self.path();
82 self.push_error(ValidationError {
83 path,
84 marker: Some(marked_yaml.span.start),
85 error: error.into(),
86 });
87 }
88
89 pub fn extend_errors(&self, errors: Vec<ValidationError>) {
91 self.errors.borrow_mut().extend(errors);
92 }
93
94 pub fn append_path<V: Into<String>>(&self, path: V) -> Context<'r> {
96 let mut new_path = self.current_path.clone();
97 new_path.push(path.into());
98 Context {
99 root_schema: self.root_schema,
100 current_schema: self.current_schema,
101 current_path: new_path,
102 errors: self.errors.clone(),
103 fail_fast: self.fail_fast,
104 stream_ended: self.stream_ended,
105 stream_started: self.stream_started,
106 resolving_refs: self.resolving_refs.clone(),
107 }
108 }
109
110 pub fn is_resolving_ref(&self, ref_name: &str, value: &saphyr::MarkedYaml) -> bool {
113 let key = (ref_name.to_string(), value.span.start.index());
114 self.resolving_refs.borrow().contains(&key)
115 }
116
117 pub fn begin_resolving_ref(&self, ref_name: &str, value: &saphyr::MarkedYaml) {
119 let key = (ref_name.to_string(), value.span.start.index());
120 self.resolving_refs.borrow_mut().insert(key);
121 }
122
123 pub fn end_resolving_ref(&self, ref_name: &str, value: &saphyr::MarkedYaml) {
125 let key = (ref_name.to_string(), value.span.start.index());
126 self.resolving_refs.borrow_mut().remove(&key);
127 }
128}