use crate::parser::{EvaluationError, ExpressionEvaluator, PathExpression};
use serde_json::Value;
use std::collections::HashMap;
pub mod advanced;
pub mod basic;
pub use advanced::*;
pub use basic::*;
pub trait BuiltinFunction: Send + Sync {
fn name(&self) -> &str;
fn execute(
&self,
args: &[Value],
input: &Value,
) -> Result<Vec<Value>, EvaluationError>;
fn description(&self) -> &str {
"No description available"
}
}
pub trait AdvancedBuiltinFunction: Send + Sync {
fn name(&self) -> &str;
fn execute_with_expressions(
&self,
args: &[PathExpression],
evaluator: &ExpressionEvaluator,
input: &Value,
) -> Result<Vec<Value>, EvaluationError>;
fn description(&self) -> &str {
"No description available"
}
}
#[derive(Default)]
pub struct FunctionRegistry {
functions: HashMap<String, Box<dyn BuiltinFunction>>,
advanced_functions: HashMap<String, Box<dyn AdvancedBuiltinFunction>>,
}
impl FunctionRegistry {
pub fn new() -> Self {
let mut registry = Self::default();
registry.register_builtin_functions();
registry
}
pub fn register(&mut self, function: Box<dyn BuiltinFunction>) {
self.functions.insert(function.name().to_string(), function);
}
pub fn register_advanced(
&mut self,
function: Box<dyn AdvancedBuiltinFunction>,
) {
self.advanced_functions
.insert(function.name().to_string(), function);
}
pub fn get(&self, name: &str) -> Option<&dyn BuiltinFunction> {
self.functions.get(name).map(|f| f.as_ref())
}
pub fn get_advanced(
&self,
name: &str,
) -> Option<&dyn AdvancedBuiltinFunction> {
self.advanced_functions.get(name).map(|f| f.as_ref())
}
fn register_builtin_functions(&mut self) {
self.register(Box::new(LengthFunction));
self.register(Box::new(TypeFunction));
self.register(Box::new(KeysFunction));
self.register(Box::new(ValuesFunction));
self.register_advanced(Box::new(MapFunction));
self.register_advanced(Box::new(SelectFunction));
self.register_advanced(Box::new(SortFunction));
self.register_advanced(Box::new(SortByFunction));
self.register_advanced(Box::new(GroupByFunction));
self.register_advanced(Box::new(UniqueFunction));
self.register_advanced(Box::new(UniqueByFunction));
self.register_advanced(Box::new(ReverseFunction));
}
}