zen_expression/functions/
registry.rs

1use crate::functions::arguments::Arguments;
2use crate::functions::{DeprecatedFunction, FunctionKind, InternalFunction};
3use crate::variable::VariableType;
4use crate::Variable;
5use nohash_hasher::{BuildNoHashHasher, IsEnabled};
6use std::cell::RefCell;
7use std::collections::HashMap;
8use std::rc::Rc;
9use strum::IntoEnumIterator;
10
11impl IsEnabled for InternalFunction {}
12impl IsEnabled for DeprecatedFunction {}
13
14pub struct FunctionRegistry {
15    internal_functions:
16        HashMap<InternalFunction, Rc<dyn FunctionDefinition>, BuildNoHashHasher<InternalFunction>>,
17    deprecated_functions: HashMap<
18        DeprecatedFunction,
19        Rc<dyn FunctionDefinition>,
20        BuildNoHashHasher<DeprecatedFunction>,
21    >,
22}
23
24impl FunctionRegistry {
25    thread_local!(
26        static INSTANCE: RefCell<FunctionRegistry> = RefCell::new(FunctionRegistry::new_internal())
27    );
28
29    pub fn get_definition(kind: &FunctionKind) -> Option<Rc<dyn FunctionDefinition>> {
30        match kind {
31            FunctionKind::Internal(internal) => {
32                Self::INSTANCE.with_borrow(|i| i.internal_functions.get(&internal).cloned())
33            }
34            FunctionKind::Deprecated(deprecated) => {
35                Self::INSTANCE.with_borrow(|i| i.deprecated_functions.get(&deprecated).cloned())
36            }
37            FunctionKind::Closure(_) => None,
38        }
39    }
40
41    fn new_internal() -> Self {
42        let internal_functions = InternalFunction::iter()
43            .map(|i| (i.clone(), (&i).into()))
44            .collect();
45
46        let deprecated_functions = DeprecatedFunction::iter()
47            .map(|i| (i.clone(), (&i).into()))
48            .collect();
49
50        Self {
51            internal_functions,
52            deprecated_functions,
53        }
54    }
55}
56
57pub trait FunctionDefinition {
58    fn required_parameters(&self) -> usize;
59    fn optional_parameters(&self) -> usize;
60    fn check_types(&self, args: &[Rc<VariableType>]) -> FunctionTypecheck;
61    fn call(&self, args: Arguments) -> anyhow::Result<Variable>;
62    fn param_type(&self, index: usize) -> String;
63    fn return_type(&self) -> String;
64}
65
66#[derive(Debug, Default)]
67pub struct FunctionTypecheck {
68    pub general: Option<String>,
69    pub arguments: Vec<(usize, String)>,
70    pub return_type: VariableType,
71}