Skip to main content

reifydb_routine/function/
registry.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use std::{collections::HashMap, ops::Deref, sync::Arc};
5
6use super::{Function, FunctionCapability};
7
8#[derive(Clone)]
9pub struct Functions(Arc<FunctionsInner>);
10
11impl Functions {
12	pub fn empty() -> Functions {
13		Functions::builder().configure()
14	}
15
16	pub fn builder() -> FunctionsConfigurator {
17		FunctionsConfigurator(FunctionsInner {
18			functions: HashMap::new(),
19		})
20	}
21}
22
23impl Deref for Functions {
24	type Target = FunctionsInner;
25
26	fn deref(&self) -> &Self::Target {
27		&self.0
28	}
29}
30
31#[derive(Clone)]
32pub struct FunctionsInner {
33	pub(crate) functions: HashMap<String, Arc<dyn Function>>,
34}
35
36impl FunctionsInner {
37	pub fn get(&self, name: &str) -> Option<Arc<dyn Function>> {
38		self.functions.get(name).cloned()
39	}
40
41	pub fn get_scalar(&self, name: &str) -> Option<Arc<dyn Function>> {
42		self.functions.get(name).cloned().filter(|f| f.capabilities().contains(&FunctionCapability::Scalar))
43	}
44
45	pub fn get_aggregate(&self, name: &str) -> Option<Arc<dyn Function>> {
46		self.functions.get(name).cloned().filter(|f| f.capabilities().contains(&FunctionCapability::Aggregate))
47	}
48
49	pub fn get_generator(&self, name: &str) -> Option<Arc<dyn Function>> {
50		self.functions.get(name).cloned().filter(|f| f.capabilities().contains(&FunctionCapability::Generator))
51	}
52
53	pub fn scalar_names(&self) -> Vec<&str> {
54		self.functions
55			.iter()
56			.filter(|(_, f)| f.capabilities().contains(&FunctionCapability::Scalar))
57			.map(|(s, _)| s.as_str())
58			.collect()
59	}
60
61	pub fn aggregate_names(&self) -> Vec<&str> {
62		self.functions
63			.iter()
64			.filter(|(_, f)| f.capabilities().contains(&FunctionCapability::Aggregate))
65			.map(|(s, _)| s.as_str())
66			.collect()
67	}
68
69	pub fn generator_names(&self) -> Vec<&str> {
70		self.functions
71			.iter()
72			.filter(|(_, f)| f.capabilities().contains(&FunctionCapability::Generator))
73			.map(|(s, _)| s.as_str())
74			.collect()
75	}
76}
77
78pub struct FunctionsConfigurator(FunctionsInner);
79
80impl FunctionsConfigurator {
81	pub fn register_function(mut self, func: Arc<dyn Function>) -> Self {
82		self.0.functions.insert(func.info().name.clone(), func);
83		self
84	}
85
86	pub fn register_alias(mut self, alias: &str, canonical: &str) -> Self {
87		if let Some(func) = self.0.functions.get(canonical).cloned() {
88			self.0.functions.insert(alias.to_string(), func);
89		}
90		self
91	}
92
93	pub fn configure(self) -> Functions {
94		Functions(Arc::new(self.0))
95	}
96}