Skip to main content

ravenrs_app/
functions.rs

1//! Functions an application adds to the criteria language, for everything that reads an expression.
2
3use 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
14/// Adds a function to expressions in rules, appearance, actions, calculated fields and filters.
15/// An application's state is of one thread, and so is this. A filter with one runs in memory, as
16/// the database does not know it.
17pub 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
24/// What an expression is evaluated with: the language and what was added to it.
25pub 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}