tulpje_framework/module/
registry.rs

1use std::collections::{HashMap, HashSet};
2
3use twilight_gateway::EventType;
4use twilight_model::application::command::Command;
5
6use super::Module;
7use crate::handler::{
8    command_handler::CommandHandler, component_interaction_handler::ComponentInteractionHandler,
9    event_handler::EventHandler, task_handler::TaskHandler,
10};
11
12#[derive(Clone)]
13#[expect(
14    clippy::partial_pub_fields,
15    reason = "we need 'tasks' to be public for now to start the task scheduler"
16)]
17pub struct Registry<T: Clone + Send + Sync> {
18    modules: HashMap<String, Module<T>>,
19
20    pub(crate) commands: HashMap<String, CommandHandler<T>>,
21    pub(crate) components: HashMap<String, ComponentInteractionHandler<T>>,
22    pub(crate) events: HashMap<EventType, HashSet<EventHandler<T>>>,
23    pub tasks: HashMap<String, TaskHandler<T>>,
24}
25
26impl<T: Clone + Send + Sync> Registry<T> {
27    pub fn new() -> Self {
28        Self {
29            modules: HashMap::new(),
30            commands: HashMap::new(),
31            components: HashMap::new(),
32            events: HashMap::new(),
33            tasks: HashMap::new(),
34        }
35    }
36
37    pub fn register(&mut self, module: Module<T>) {
38        self.commands.extend(module.commands.clone());
39        self.components.extend(module.components.clone());
40        self.events.extend(module.events.clone());
41        self.tasks.extend(module.tasks.clone());
42
43        self.modules.insert(module.name.clone(), module);
44    }
45
46    pub fn global_commands(&self) -> Vec<Command> {
47        self.modules
48            .values()
49            .filter(|m| !m.guild_scoped) // filter out guild scoped modules
50            .flat_map(|m| m.command_definitions.clone())
51            .collect()
52    }
53
54    pub fn module_commands(&self, module: &str) -> Option<Vec<Command>> {
55        Some(self.modules.get(module)?.command_definitions.clone())
56    }
57
58    pub fn find_command(&self, name: &str) -> Option<&CommandHandler<T>> {
59        self.commands.get(name)
60    }
61
62    pub fn guild_module_names(&self) -> Vec<String> {
63        self.modules
64            .values()
65            .filter(|m| m.guild_scoped)
66            .map(|m| m.name.clone())
67            .collect()
68    }
69}
70
71impl<T: Clone + Send + Sync> Default for Registry<T> {
72    fn default() -> Self {
73        Self::new()
74    }
75}