datalogic_rs/arena/
custom.rs1use crate::arena::DataArena;
2use crate::logic::Result;
3use crate::value::DataValue;
4use crate::LogicError;
5use std::collections::HashMap;
6use std::fmt;
7
8pub trait CustomOperator: fmt::Debug + Send + Sync {
10 fn evaluate<'a>(
15 &self,
16 args: &'a [DataValue<'a>],
17 arena: &'a DataArena,
18 ) -> Result<&'a DataValue<'a>>;
19}
20
21#[derive(Default)]
23pub struct CustomOperatorRegistry {
24 operators: HashMap<String, Box<dyn CustomOperator>>,
25}
26
27impl CustomOperatorRegistry {
28 pub fn new() -> Self {
30 Self {
31 operators: HashMap::new(),
32 }
33 }
34
35 pub fn register(&mut self, name: &str, operator: Box<dyn CustomOperator>) {
37 self.operators.insert(name.to_string(), operator);
38 }
39
40 pub fn get(&self, name: &str) -> Option<&dyn CustomOperator> {
42 self.operators.get(name).map(|op| op.as_ref())
43 }
44}
45
46pub type SimpleOperatorFn = fn(Vec<DataValue>) -> std::result::Result<DataValue, String>;
52
53#[derive(Debug)]
58pub struct SimpleOperatorAdapter {
59 function: SimpleOperatorFn,
60 name: String,
61}
62
63impl SimpleOperatorAdapter {
64 pub fn new(name: &str, function: SimpleOperatorFn) -> Self {
66 Self {
67 function,
68 name: name.to_string(),
69 }
70 }
71}
72
73impl CustomOperator for SimpleOperatorAdapter {
74 fn evaluate<'a>(
75 &self,
76 args: &'a [DataValue<'a>],
77 arena: &'a DataArena,
78 ) -> Result<&'a DataValue<'a>> {
79 let owned_args = args.iter().map(|arg| arg.to_owned()).collect::<Vec<_>>();
81
82 match (self.function)(owned_args) {
84 Ok(result) => {
85 match result {
87 DataValue::Null => Ok(arena.null_value()),
88 DataValue::Bool(true) => Ok(arena.true_value()),
89 DataValue::Bool(false) => Ok(arena.false_value()),
90 DataValue::Number(n) => Ok(arena.alloc(DataValue::Number(n))),
91 DataValue::String(s) => {
92 let s_arena = arena.alloc_str(s);
93 Ok(arena.alloc(DataValue::String(s_arena)))
94 }
95 DataValue::Array(_) | DataValue::Object(_) => {
97 let str_rep = format!("{:?}", result);
98 let s_arena = arena.alloc_str(&str_rep);
99 Ok(arena.alloc(DataValue::String(s_arena)))
100 }
101 DataValue::DateTime(dt) => Ok(arena.alloc(DataValue::DateTime(dt))),
103 DataValue::Duration(dur) => Ok(arena.alloc(DataValue::Duration(dur))),
104 }
105 }
106 Err(msg) => Err(LogicError::ParseError {
107 reason: format!("Error in operator '{}': {}", self.name, msg),
108 }),
109 }
110 }
111}