filter_expr_evaler/
ctx.rs1use std::{
2 collections::BTreeMap,
3 fmt::{self, Debug},
4};
5
6use crate::Value;
7
8use crate::Error;
9
10#[async_trait::async_trait]
12pub trait Context: Send + Sync {
13 async fn get_var(&self, name: &str) -> Result<Option<Value>, Error>;
22
23 fn get_fn(&self, name: &str) -> Option<&BoxedExprFn> {
27 let _name = name;
28
29 None
30 }
31}
32
33#[macro_export]
46macro_rules! simple_context {
47 () => {
49 $crate::SimpleContext::new(std::collections::BTreeMap::new())
50 };
51
52 ($key:literal : $value:expr $(,)?) => {
54 $crate::SimpleContext::new(std::collections::BTreeMap::from([
55 ($key.to_string(), ($value).into()),
56 ]))
57 };
58
59 ($key:literal : $value:expr, $($rest_key:literal : $rest_value:expr),* $(,)?) => {
61 $crate::SimpleContext::new(std::collections::BTreeMap::from([
62 ($key.to_string(), ($value).into()),
63 $(($rest_key.to_string(), ($rest_value).into())),*
64 ]))
65 };
66}
67
68pub struct SimpleContext {
73 vars: BTreeMap<String, Value>,
74 fns: BTreeMap<String, BoxedExprFn>,
75}
76
77impl Debug for SimpleContext {
78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79 let fns_len = self.fns.len();
80 write!(
81 f,
82 "SimpleContext {{ vars: {:?}, fns: [{:?} fns] }}",
83 self.vars, fns_len
84 )?;
85 Ok(())
86 }
87}
88
89impl SimpleContext {
90 pub fn new(vars: BTreeMap<String, Value>) -> Self {
91 Self {
92 vars,
93 fns: BTreeMap::new(),
94 }
95 }
96
97 pub fn add_fn(&mut self, name: String, func: BoxedExprFn) {
98 self.fns.insert(name, func);
99 }
100}
101
102#[async_trait::async_trait]
103impl Context for SimpleContext {
104 async fn get_var(&self, name: &str) -> Result<Option<Value>, Error> {
105 Ok(self.vars.get(name).cloned())
106 }
107
108 fn get_fn(&self, name: &str) -> Option<&BoxedExprFn> {
109 self.fns.get(name)
110 }
111}
112
113pub struct ExprFnContext {
114 pub args: Vec<Value>,
115}
116
117#[async_trait::async_trait]
118pub trait ExprFn: Send + Sync {
119 async fn call(&self, ctx: ExprFnContext) -> Result<Value, Error>;
120}
121
122pub type BoxedExprFn = Box<dyn ExprFn>;