wpl/eval/builtins/
registry.rs1use once_cell::sync::Lazy;
2use smol_str::SmolStr;
3use std::collections::HashMap;
4use std::sync::{Mutex, MutexGuard};
5
6use super::PipeHold;
7
8pub type PlgPipeUnitBuilder = fn() -> PipeHold;
9
10#[derive(Default)]
11struct PlgPipeUnitRegistry {
12 builders: HashMap<SmolStr, PlgPipeUnitBuilder>,
13}
14
15impl PlgPipeUnitRegistry {
16 fn register(&mut self, name: &str, builder: PlgPipeUnitBuilder) {
17 self.builders
18 .insert(SmolStr::from(name.to_ascii_uppercase()), builder);
19 }
20
21 fn create(&self, name: &str) -> Option<PipeHold> {
22 self.builders
23 .get(&SmolStr::from(name.to_ascii_uppercase()))
24 .map(|builder| (builder)())
25 }
26
27 fn list(&self) -> Vec<SmolStr> {
28 self.builders.keys().cloned().collect()
29 }
30}
31
32static PIPE_UNIT_REGISTRY: Lazy<Mutex<PlgPipeUnitRegistry>> =
33 Lazy::new(|| Mutex::new(PlgPipeUnitRegistry::default()));
34
35fn registry() -> MutexGuard<'static, PlgPipeUnitRegistry> {
36 PIPE_UNIT_REGISTRY
37 .lock()
38 .expect("plg_pipe unit registry poisoned")
39}
40
41pub fn register_pipe_unit(name: &str, builder: PlgPipeUnitBuilder) {
42 registry().register(name, builder);
43}
44
45pub fn create_pipe_unit(name: &str) -> Option<PipeHold> {
46 registry().create(name)
47}
48
49pub fn list_pipe_units() -> Vec<SmolStr> {
50 registry().list()
51}
52
53#[macro_export]
54macro_rules! register_wpl_pipe {
55 ($name:expr, $builder:expr) => {
56 $crate::eval::builtins::registry::register_pipe_unit(
57 $name,
58 $builder as $crate::eval::builtins::registry::PlgPipeUnitBuilder,
59 );
60 };
61
62 ($($name:expr => $builder:expr),* $(,)?) => {
63 $crate::eval::builtins::registry::register_pipe_unit_batch(vec![
64 $(
65 $name => $builder as $crate::eval::builtins::registry::PlgPipeUnitBuilder
66 ),*
67 ]);
68 };
69}
70
71pub fn register_wpl_pipe_batch<I>(items: I)
72where
73 I: IntoIterator<Item = (&'static str, PlgPipeUnitBuilder)>,
74{
75 let mut guard = registry();
76 for (name, builder) in items {
77 guard.register(name, builder);
78 }
79}