1use std::collections::HashMap;
2
3use crate::{Error, expr::{BoxedExprFn, ExprValue}};
4
5#[macro_export]
18macro_rules! simple_context {
19 () => {
21 $crate::SimpleContext::new(std::collections::HashMap::new())
22 };
23
24 ($key:literal : $value:expr $(,)?) => {
26 $crate::SimpleContext::new(std::collections::HashMap::from([
27 ($key.to_string(), ($value).into()),
28 ]))
29 };
30
31 ($key:literal : $value:expr, $($rest_key:literal : $rest_value:expr),* $(,)?) => {
33 $crate::SimpleContext::new(std::collections::HashMap::from([
34 ($key.to_string(), ($value).into()),
35 $(($rest_key.to_string(), ($rest_value).into())),*
36 ]))
37 };
38}
39
40#[async_trait::async_trait]
42pub trait Context: Send + Sync {
43 async fn get_var(&self, name: &str) -> Result<ExprValue, Error>;
44
45 async fn get_fn(&self, name: &str) -> Option<&BoxedExprFn> {
46 let _name = name;
47
48 None
49 }
50}
51
52pub struct SimpleContext {
57 vars: HashMap<String, ExprValue>,
58 fns: HashMap<String, BoxedExprFn>,
59}
60
61impl SimpleContext {
62 pub fn new(vars: HashMap<String, ExprValue>) -> Self {
63 Self {
64 vars,
65 fns: HashMap::new(),
66 }
67 }
68
69 pub fn add_fn(&mut self, name: String, func: BoxedExprFn) {
70 self.fns.insert(name, func);
71 }
72}
73
74#[async_trait::async_trait]
75impl Context for SimpleContext {
76 async fn get_var(&self, name: &str) -> Result<ExprValue, Error> {
77 self.vars
78 .get(name)
79 .cloned()
80 .ok_or(Error::NoSuchVar(name.to_string()))
81 }
82
83 async fn get_fn(&self, name: &str) -> Option<&BoxedExprFn> {
84 self.fns.get(name)
85 }
86}