xee_interpreter/context/
dynamic_context_builder.rs1use std::{cell::RefCell, ops::Deref, rc::Rc};
2
3use ahash::{HashMap, HashMapExt};
4use iri_string::types::{IriStr, IriString};
5
6use crate::{interpreter, sequence, xml};
7
8use super::{DynamicContext, Variables};
9
10#[derive(Debug, Clone)]
18pub struct DynamicContextBuilder<'a> {
19 program: &'a interpreter::Program,
20 context_item: Option<sequence::Item>,
21 documents: DocumentsRef,
22 variables: Variables,
23 current_datetime: chrono::DateTime<chrono::offset::FixedOffset>,
24 default_collection: Option<sequence::Sequence>,
25 collections: HashMap<IriString, sequence::Sequence>,
26 default_uri_collection: Option<sequence::Sequence>,
27 uri_collections: HashMap<IriString, sequence::Sequence>,
28 environment_variables: HashMap<String, String>,
29}
30
31#[derive(Debug, Clone)]
32pub struct DocumentsRef(Rc<RefCell<xml::Documents>>);
33
34impl Deref for DocumentsRef {
35 type Target = RefCell<xml::Documents>;
36
37 fn deref(&self) -> &Self::Target {
38 &self.0
39 }
40}
41
42impl From<xml::Documents> for DocumentsRef {
43 fn from(documents: xml::Documents) -> Self {
44 Self(Rc::new(RefCell::new(documents)))
45 }
46}
47
48impl DocumentsRef {
49 pub fn new() -> Self {
50 Self(Rc::new(RefCell::new(xml::Documents::new())))
51 }
52}
53
54impl Default for DocumentsRef {
55 fn default() -> Self {
56 Self::new()
57 }
58}
59
60impl<'a> DynamicContextBuilder<'a> {
61 pub(crate) fn new(program: &'a interpreter::Program) -> Self {
63 Self {
64 program,
65 context_item: None,
66 documents: DocumentsRef::new(),
67 variables: Variables::new(),
68 current_datetime: chrono::offset::Local::now().into(),
69 default_collection: None,
70 collections: HashMap::new(),
71 default_uri_collection: None,
72 uri_collections: HashMap::new(),
73 environment_variables: HashMap::new(),
74 }
75 }
76
77 pub fn context_item(&mut self, context_item: sequence::Item) -> &mut Self {
81 self.context_item = Some(context_item);
82 self
83 }
84
85 pub fn context_node(&mut self, node: xot::Node) -> &mut Self {
87 self.context_item(sequence::Item::Node(node));
88 self
89 }
90
91 pub fn documents(&mut self, documents: impl Into<DocumentsRef>) -> &mut Self {
95 self.documents = documents.into();
96 self
97 }
98
99 pub fn variables(&mut self, variables: Variables) -> &mut Self {
103 self.variables = variables;
104 self
105 }
106
107 pub fn current_datetime(
111 &mut self,
112 current_datetime: chrono::DateTime<chrono::offset::FixedOffset>,
113 ) -> &mut Self {
114 self.current_datetime = current_datetime;
115 self
116 }
117
118 pub fn default_collection(&mut self, sequence: sequence::Sequence) -> &mut Self {
120 self.default_collection = Some(sequence);
121 self
122 }
123
124 pub fn collection(&mut self, uri: &IriStr, sequence: sequence::Sequence) -> &mut Self {
126 self.collections.insert((*uri).into(), sequence);
127 self
128 }
129
130 pub fn default_uri_collection(&mut self, uris: &[&IriStr]) -> &mut Self {
132 self.default_uri_collection = Some(Self::uris_into_sequence(uris));
133 self
134 }
135
136 pub fn uri_collection(&mut self, uri: &IriStr, uris: &[&IriStr]) -> &mut Self {
138 self.uri_collections
139 .insert((*uri).into(), Self::uris_into_sequence(uris));
140 self
141 }
142
143 pub fn environment_variables(
145 &mut self,
146 environment_variables: HashMap<String, String>,
147 ) -> &mut Self {
148 self.environment_variables = environment_variables;
149 self
150 }
151
152 pub fn initialize_env(&mut self) -> &mut Self {
154 self.environment_variables = std::env::vars().collect();
155 self
156 }
157
158 fn uris_into_sequence(uris: &[&IriStr]) -> sequence::Sequence {
159 let items: Vec<sequence::Item> = uris
161 .iter()
162 .map(|uri| {
163 let iri_string: IriString = (*uri).into();
164 iri_string.into()
165 })
166 .collect();
167 items.into()
168 }
169
170 pub fn build(&self) -> DynamicContext {
172 DynamicContext::new(
173 self.program,
174 self.context_item.clone(),
175 self.documents.clone(),
176 self.variables.clone(),
177 self.current_datetime,
178 self.default_collection.clone(),
179 self.collections.clone(),
180 self.default_uri_collection.clone(),
181 self.uri_collections.clone(),
182 self.environment_variables.clone(),
183 )
184 }
185}