zen_expression/functions/
method.rs

1use crate::functions::date_method::DateMethod;
2use crate::functions::defs::FunctionDefinition;
3use nohash_hasher::{BuildNoHashHasher, IsEnabled};
4use std::cell::RefCell;
5use std::collections::HashMap;
6use std::fmt::Display;
7use std::rc::Rc;
8use strum::IntoEnumIterator;
9
10impl IsEnabled for DateMethod {}
11
12#[derive(Debug, PartialEq, Eq, Clone)]
13pub enum MethodKind {
14    DateMethod(DateMethod),
15}
16
17impl TryFrom<&str> for MethodKind {
18    type Error = strum::ParseError;
19
20    fn try_from(value: &str) -> Result<Self, Self::Error> {
21        DateMethod::try_from(value).map(MethodKind::DateMethod)
22    }
23}
24
25impl Display for MethodKind {
26    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27        match self {
28            MethodKind::DateMethod(d) => write!(f, "{d}"),
29        }
30    }
31}
32
33pub struct MethodRegistry {
34    date_methods: HashMap<DateMethod, Rc<dyn FunctionDefinition>, BuildNoHashHasher<DateMethod>>,
35}
36
37impl MethodRegistry {
38    thread_local!(
39        static INSTANCE: RefCell<MethodRegistry> = RefCell::new(MethodRegistry::new_internal())
40    );
41
42    pub fn get_definition(kind: &MethodKind) -> Option<Rc<dyn FunctionDefinition>> {
43        match kind {
44            MethodKind::DateMethod(dm) => {
45                Self::INSTANCE.with_borrow(|i| i.date_methods.get(&dm).cloned())
46            }
47        }
48    }
49
50    fn new_internal() -> Self {
51        let date_methods = DateMethod::iter()
52            .map(|i| (i.clone(), (&i).into()))
53            .collect();
54
55        Self { date_methods }
56    }
57}