expression_engine 0.7.0

An expression engine written in pure rust
Documentation
use once_cell::sync::OnceCell;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};

#[derive(Hash, Eq, PartialEq)]
enum DescriptorKey {
    UNARY(String),
    BINARY(String),
    POSTFIX(String),
    TERNARY,
    FUNCTION(String),
    REFERENCE(String),
    LIST,
    MAP,
    CHAIN,
}

#[derive(Clone)]
enum Descriptor {
    UNARY(Arc<UnaryDescriptor>),
    BINARY(Arc<BinaryDescriptor>),
    POSTFIX(Arc<PostfixDescriptor>),
    TERNARY(Arc<TernaryDescriptor>),
    FUNCTION(Arc<FunctionDescriptor>),
    REFERENCE(Arc<ReferenceDescriptor>),
    LIST(Arc<ListDescriptor>),
    MAP(Arc<MapDescriptor>),
    CHAIN(Arc<ChainDescriptor>),
}

type UnaryDescriptor = dyn Fn(String, String) -> String + Send + Sync + 'static;
type BinaryDescriptor = dyn Fn(String, String, String) -> String + Send + Sync + 'static;
type PostfixDescriptor = dyn Fn(String, String) -> String + Send + Sync + 'static;
type TernaryDescriptor = dyn Fn(String, String, String) -> String + Send + Sync + 'static;
type FunctionDescriptor = dyn Fn(String, Vec<String>) -> String + Send + Sync + 'static;
type ReferenceDescriptor = dyn Fn(String) -> String + Send + Sync + 'static;
type ListDescriptor = dyn Fn(Vec<String>) -> String + Send + Sync + 'static;
type MapDescriptor = dyn Fn(Vec<(String, String)>) -> String + Send + Sync + 'static;
type ChainDescriptor = dyn Fn(Vec<String>) -> String + Send + Sync + 'static;

pub struct DescriptorManager {
    store: &'static Mutex<HashMap<DescriptorKey, Descriptor>>,
}

impl DescriptorManager {
    pub fn new() -> Self {
        static STORE: OnceCell<Mutex<HashMap<DescriptorKey, Descriptor>>> = OnceCell::new();
        let store = STORE.get_or_init(|| Mutex::new(HashMap::new()));
        DescriptorManager { store }
    }

    fn set(&mut self, key: DescriptorKey, value: Descriptor) {
        let mut binding = self.store.lock().unwrap();
        binding.insert(key, value);
    }

    fn get(&self, key: DescriptorKey) -> Option<Descriptor> {
        let binding = self.store.lock().unwrap();
        let value = binding.get(&key);
        if value.is_none() {
            return None;
        }
        Some(value.unwrap().clone())
    }

    pub fn set_unary_descriptor(&mut self, op: String, descriptor: Arc<UnaryDescriptor>) {
        let key = DescriptorKey::UNARY(op);
        let value = Descriptor::UNARY(descriptor);
        self.set(key, value)
    }

    pub fn get_unary_descriptor(&self, op: String) -> Arc<UnaryDescriptor> {
        let key = DescriptorKey::UNARY(op);
        let v = self.get(key);
        if v.is_none() {
            return Arc::new(default_unary_descriptor);
        }
        match v.unwrap() {
            Descriptor::UNARY(f) => f.clone(),
            _ => Arc::new(default_unary_descriptor),
        }
    }

    pub fn set_binary_descriptor(&mut self, op: String, descriptor: Arc<BinaryDescriptor>) {
        let key = DescriptorKey::BINARY(op);
        let value = Descriptor::BINARY(descriptor);
        self.set(key, value)
    }

    pub fn get_binary_descriptor(&self, op: String) -> Arc<BinaryDescriptor> {
        let key = DescriptorKey::UNARY(op);
        let v = self.get(key);
        if v.is_none() {
            return Arc::new(default_binary_descriptor);
        }
        match v.unwrap() {
            Descriptor::BINARY(f) => f.clone(),
            _ => Arc::new(default_binary_descriptor),
        }
    }

    pub fn set_postfix_descriptor(&mut self, op: String, descriptor: Arc<UnaryDescriptor>) {
        let key = DescriptorKey::POSTFIX(op);
        let value = Descriptor::POSTFIX(descriptor);
        self.set(key, value)
    }

    pub fn get_postfix_descriptor(&self, op: String) -> Arc<UnaryDescriptor> {
        let key = DescriptorKey::POSTFIX(op);
        let v = self.get(key);
        if v.is_none() {
            return Arc::new(default_postfix_descriptor);
        }
        match v.unwrap() {
            Descriptor::POSTFIX(f) => f.clone(),
            _ => Arc::new(default_unary_descriptor),
        }
    }

    pub fn set_ternary_descriptor(&mut self, descriptor: Arc<TernaryDescriptor>) {
        let key = DescriptorKey::TERNARY;
        let value = Descriptor::TERNARY(descriptor);
        self.set(key, value)
    }

    pub fn get_ternary_descriptor(&self) -> Arc<TernaryDescriptor> {
        let key = DescriptorKey::TERNARY;
        let v = self.get(key);
        if v.is_none() {
            return Arc::new(default_ternary_descriptor);
        }
        match v.unwrap() {
            Descriptor::TERNARY(f) => f.clone(),
            _ => Arc::new(default_binary_descriptor),
        }
    }

    pub fn set_function_descriptor(&mut self, name: String, descriptor: Arc<FunctionDescriptor>) {
        let key = DescriptorKey::FUNCTION(name);
        let value = Descriptor::FUNCTION(descriptor);
        self.set(key, value)
    }

    pub fn get_function_descriptor(&self, name: String) -> Arc<FunctionDescriptor> {
        let key = DescriptorKey::FUNCTION(name);
        let v = self.get(key);
        if v.is_none() {
            return Arc::new(default_function_descriptor);
        }
        match v.unwrap() {
            Descriptor::FUNCTION(f) => f.clone(),
            _ => Arc::new(default_function_descriptor),
        }
    }

    pub fn set_reference_descriptor(&mut self, name: String, descriptor: Arc<ReferenceDescriptor>) {
        let key = DescriptorKey::REFERENCE(name);
        let value = Descriptor::REFERENCE(descriptor);
        self.set(key, value)
    }

    pub fn get_reference_descriptor(&self, name: String) -> Arc<ReferenceDescriptor> {
        let key = DescriptorKey::REFERENCE(name);
        let v = self.get(key);
        if v.is_none() {
            return Arc::new(default_reference_descriptor);
        }
        match v.unwrap() {
            Descriptor::REFERENCE(f) => f.clone(),
            _ => Arc::new(default_reference_descriptor),
        }
    }

    pub fn set_list_descriptor(&mut self, descriptor: Arc<ListDescriptor>) {
        let key = DescriptorKey::LIST;
        let value = Descriptor::LIST(descriptor);
        self.set(key, value)
    }

    pub fn get_list_descriptor(&self) -> Arc<ListDescriptor> {
        let key = DescriptorKey::LIST;
        let v = self.get(key);
        if v.is_none() {
            return Arc::new(default_list_descriptor);
        }
        match v.unwrap() {
            Descriptor::LIST(f) => f.clone(),
            _ => Arc::new(default_list_descriptor),
        }
    }

    pub fn set_map_descriptor(&mut self, descriptor: Arc<MapDescriptor>) {
        let key = DescriptorKey::MAP;
        let value = Descriptor::MAP(descriptor);
        self.set(key, value)
    }

    pub fn get_map_descriptor(&self) -> Arc<MapDescriptor> {
        let key = DescriptorKey::MAP;
        let v = self.get(key);
        if v.is_none() {
            return Arc::new(default_map_descriptor);
        }
        match v.unwrap() {
            Descriptor::MAP(f) => f.clone(),
            _ => Arc::new(default_map_descriptor),
        }
    }

    pub fn set_chain_descriptor(&mut self, descriptor: Arc<ChainDescriptor>) {
        let key = DescriptorKey::CHAIN;
        let value = Descriptor::CHAIN(descriptor);
        self.set(key, value)
    }

    pub fn get_chain_descriptor(&self) -> Arc<ChainDescriptor> {
        let key = DescriptorKey::CHAIN;
        let v = self.get(key);
        if v.is_none() {
            return Arc::new(default_chain_descriptor);
        }
        match v.unwrap() {
            Descriptor::CHAIN(f) => f.clone(),
            _ => Arc::new(default_chain_descriptor),
        }
    }
}

fn default_unary_descriptor(op: String, rhs: String) -> String {
    op + &rhs
}

fn default_binary_descriptor(op: String, lhs: String, rhs: String) -> String {
    lhs + &op + &rhs
}

fn default_postfix_descriptor(lhs: String, op: String) -> String {
    lhs + &op
}

fn default_ternary_descriptor(condition: String, lhs: String, rhs: String) -> String {
    condition + "?" + &lhs + ":" + &rhs
}

fn default_function_descriptor(name: String, params: Vec<String>) -> String {
    name + "(" + &params.join(",") + ")"
}

fn default_reference_descriptor(name: String) -> String {
    name
}

fn default_list_descriptor(params: Vec<String>) -> String {
    "[".to_string() + &params.join(",") + "]"
}

fn default_map_descriptor(m: Vec<(String, String)>) -> String {
    let mut tmp = Vec::new();
    for (k, v) in m {
        tmp.push(k + ":" + &v)
    }
    "{".to_string() + &tmp.join(",") + "}"
}

fn default_chain_descriptor(params: Vec<String>) -> String {
    params.join(";")
}

#[cfg(test)]
mod tests {
    use super::default_binary_descriptor;
    use super::default_chain_descriptor;
    use super::default_function_descriptor;
    use super::default_list_descriptor;
    use super::default_map_descriptor;
    use super::default_postfix_descriptor;
    use super::default_reference_descriptor;
    use super::default_ternary_descriptor;
    use super::default_unary_descriptor;
    use super::DescriptorManager;
    use std::sync::Arc;

    #[test]
    fn test_register() {
        DescriptorManager::new()
            .set_binary_descriptor("haha".to_string(), Arc::new(default_binary_descriptor));
        DescriptorManager::new().set_chain_descriptor(Arc::new(default_chain_descriptor));
        DescriptorManager::new()
            .set_function_descriptor("haha".to_string(), Arc::new(default_function_descriptor));
        DescriptorManager::new().set_list_descriptor(Arc::new(default_list_descriptor));
        DescriptorManager::new().set_map_descriptor(Arc::new(default_map_descriptor));
        DescriptorManager::new()
            .set_reference_descriptor("haha".to_string(), Arc::new(default_reference_descriptor));
        DescriptorManager::new().set_ternary_descriptor(Arc::new(default_ternary_descriptor));
        DescriptorManager::new()
            .set_unary_descriptor("haha".to_string(), Arc::new(default_unary_descriptor));
        DescriptorManager::new()
            .set_postfix_descriptor("haha".to_string(), Arc::new(default_postfix_descriptor))
    }
}