1#![warn(missing_docs)]
4
5use crate::{ExtDataType, FnInfo, MyError, add_builtins, crs::CRS};
9use core::fmt;
10use std::{any::Any, collections::HashMap, rc::Rc};
11
12pub struct Context {
15 crs: CRS,
16 pub(crate) functions: HashMap<String, FnInfo>,
17}
18
19impl fmt::Debug for Context {
20 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21 f.debug_struct("Context")
22 .field("crs", &self.crs)
23 .field("functions", &self.functions)
24 .finish()
25 }
26}
27
28impl Default for Context {
29 fn default() -> Self {
30 Self::new()
31 }
32}
33
34impl Context {
35 pub fn new() -> Self {
38 Context {
39 crs: CRS::default(),
40 functions: HashMap::with_capacity(5),
41 }
42 }
43
44 pub fn try_with_crs(crs_code: &str) -> Result<Self, MyError> {
48 let mut result = Self::new();
49 result.crs = CRS::new(crs_code)?;
50 Ok(result)
51 }
52
53 pub fn register<F>(
56 &mut self,
57 name: &str,
58 arg_types: Vec<ExtDataType>,
59 result_type: ExtDataType,
60 closure: F,
61 ) where
62 F: Fn(Vec<Box<dyn Any>>) -> Option<Box<dyn Any>> + Send + Sync + 'static,
63 {
64 self.functions.insert(
65 name.to_string(),
66 FnInfo {
67 closure: Box::new(closure),
68 arg_types,
69 result_type,
70 },
71 );
72 }
73
74 pub fn freeze(self) -> SharedContext {
77 Rc::new(self)
78 }
79
80 pub fn crs(&self) -> &CRS {
82 &self.crs
83 }
84
85 pub fn fn_info(&self, name: &str) -> Option<&FnInfo> {
87 self.functions.get(name)
88 }
89
90 pub fn register_builtins(&mut self) {
92 add_builtins(self);
93 }
94}
95
96pub type SharedContext = Rc<Context>;