use alloc::boxed::Box;
use alloc::collections::{BTreeMap, BTreeSet};
use alloc::rc::Rc;
use alloc::string::String;
use core::cell::RefCell;
use crate::draft::Draft;
use crate::error::ValidationError;
use crate::formats::FormatChecker;
use crate::keywords::custom::KeywordFactory;
use crate::paths::Location;
use crate::referencing::{Resolved, Resolver, VocabularySet};
pub(crate) type InProgress = Rc<RefCell<BTreeSet<String>>>;
pub struct CompilerContext<'a> {
pub resolver: Resolver<'a>,
pub schema_path: Location,
pub vocabulary: VocabularySet,
pub in_progress: InProgress,
pub draft: Draft,
pub assert_format: bool,
pub custom_formats: BTreeMap<String, Box<dyn FormatChecker>>,
pub custom_keywords: BTreeMap<String, Box<dyn KeywordFactory>>,
pub depth: u32,
}
impl<'a> CompilerContext<'a> {
pub fn new(
resolver: Resolver<'a>,
schema_path: Location,
vocabulary: VocabularySet,
draft: Draft,
assert_format: bool,
custom_formats: BTreeMap<String, Box<dyn FormatChecker>>,
custom_keywords: BTreeMap<String, Box<dyn KeywordFactory>>,
) -> Self {
Self {
resolver,
schema_path,
vocabulary,
in_progress: Rc::new(RefCell::new(BTreeSet::new())),
draft,
assert_format,
custom_formats,
custom_keywords,
depth: 0,
}
}
pub fn push_keyword(&self, keyword: &str) -> Self {
let mut new_path = self.schema_path.clone();
new_path.push_property(keyword);
Self {
resolver: self.resolver.clone(),
schema_path: new_path,
vocabulary: self.vocabulary.clone(),
in_progress: Rc::clone(&self.in_progress),
draft: self.draft,
assert_format: self.assert_format,
custom_formats: self.custom_formats.clone(),
custom_keywords: self.custom_keywords.clone(),
depth: self.depth + 1,
}
}
pub fn with_resolver(&self, resolver: Resolver<'a>, keyword: &str) -> Self {
let mut new_path = self.schema_path.clone();
new_path.push_property(keyword);
Self {
resolver,
schema_path: new_path,
vocabulary: self.vocabulary.clone(),
in_progress: Rc::clone(&self.in_progress),
draft: self.draft,
assert_format: self.assert_format,
custom_formats: self.custom_formats.clone(),
custom_keywords: self.custom_keywords.clone(),
depth: self.depth + 1,
}
}
#[allow(dead_code)]
pub fn resolve_ref(&self, reference: &str) -> Result<Resolved<'a>, ValidationError> {
self.resolver.lookup(reference)
}
pub fn is_in_progress(&self, uri: &str) -> bool {
self.in_progress.borrow().contains(uri)
}
pub fn mark_in_progress(&self, uri: &str) {
self.in_progress.borrow_mut().insert(uri.to_string());
}
pub fn mark_done(&self, uri: &str) {
self.in_progress.borrow_mut().remove(uri);
}
}