zen_expression/functions/
registry.rs1use 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}