use std::cell::RefCell;
use std::collections::HashSet;
use std::rc::Rc;
use crate::RootSchema;
use crate::YamlSchema;
use crate::validation::ValidationError;
#[derive(Debug, Default)]
pub struct Context<'r> {
pub root_schema: Option<&'r RootSchema<'r>>,
pub current_schema: Option<&'r YamlSchema<'r>>,
pub current_path: Vec<String>,
pub stream_started: bool,
pub stream_ended: bool,
pub errors: Rc<RefCell<Vec<ValidationError>>>,
pub fail_fast: bool,
pub resolving_refs: Rc<RefCell<HashSet<(String, usize)>>>,
}
impl<'r> Context<'r> {
pub fn has_errors(&self) -> bool {
!self.errors.borrow().is_empty()
}
pub fn path(&self) -> String {
self.current_path.join(".")
}
pub fn new(fail_fast: bool) -> Context<'r> {
Context {
fail_fast,
..Default::default()
}
}
pub fn get_sub_context(&self) -> Context<'r> {
Context {
root_schema: self.root_schema,
current_schema: self.current_schema,
current_path: self.current_path.clone(),
stream_started: self.stream_started,
stream_ended: self.stream_ended,
errors: Rc::new(RefCell::new(Vec::new())),
fail_fast: self.fail_fast,
resolving_refs: self.resolving_refs.clone(),
}
}
pub fn with_root_schema(root_schema: &'r RootSchema, fail_fast: bool) -> Context<'r> {
Context {
root_schema: Some(root_schema),
fail_fast,
..Default::default()
}
}
fn push_error(&self, error: ValidationError) {
self.errors.borrow_mut().push(error);
}
pub fn add_doc_error<V: Into<String>>(&self, error: V) {
let path = self.path();
self.push_error(ValidationError {
path,
marker: None,
error: error.into(),
});
}
pub fn add_error<V: Into<String>>(&self, marked_yaml: &saphyr::MarkedYaml, error: V) {
let path = self.path();
self.push_error(ValidationError {
path,
marker: Some(marked_yaml.span.start),
error: error.into(),
});
}
pub fn extend_errors(&self, errors: Vec<ValidationError>) {
self.errors.borrow_mut().extend(errors);
}
pub fn append_path<V: Into<String>>(&self, path: V) -> Context<'r> {
let mut new_path = self.current_path.clone();
new_path.push(path.into());
Context {
root_schema: self.root_schema,
current_schema: self.current_schema,
current_path: new_path,
errors: self.errors.clone(),
fail_fast: self.fail_fast,
stream_ended: self.stream_ended,
stream_started: self.stream_started,
resolving_refs: self.resolving_refs.clone(),
}
}
pub fn is_resolving_ref(&self, ref_name: &str, value: &saphyr::MarkedYaml) -> bool {
let key = (ref_name.to_string(), value.span.start.index());
self.resolving_refs.borrow().contains(&key)
}
pub fn begin_resolving_ref(&self, ref_name: &str, value: &saphyr::MarkedYaml) {
let key = (ref_name.to_string(), value.span.start.index());
self.resolving_refs.borrow_mut().insert(key);
}
pub fn end_resolving_ref(&self, ref_name: &str, value: &saphyr::MarkedYaml) {
let key = (ref_name.to_string(), value.span.start.index());
self.resolving_refs.borrow_mut().remove(&key);
}
}