1use std::cell::RefCell;
4use std::rc::Rc;
5
6use ravenrs_criteria::{Environment, Value};
7
8type Function = Rc<dyn Fn(&[Value]) -> Result<Value, String>>;
9
10thread_local! {
11 static FUNCTIONS: RefCell<Vec<(String, Function)>> = const { RefCell::new(Vec::new()) };
12}
13
14pub fn register_function(
18 name: impl Into<String>,
19 function: impl Fn(&[Value]) -> Result<Value, String> + 'static,
20) {
21 FUNCTIONS.with(|all| all.borrow_mut().push((name.into(), Rc::new(function))));
22}
23
24pub fn environment() -> Environment {
26 FUNCTIONS.with(|all| {
27 all.borrow().iter().fold(Environment::new(), |environment, (name, function)| {
28 let function = function.clone();
29 environment.register(name, move |values| function(values))
30 })
31 })
32}