Files
payphone/src/framework/interactions/registry.rs
T
2025-08-10 21:15:53 -03:00

76 lines
2.2 KiB
Rust

use std::sync::Arc;
use scc::HashMap;
use twilight_model::{
application::interaction::InteractionData, gateway::payload::incoming::InteractionCreate,
};
use crate::framework::{
interactions::{InteractionError, context::InteractionContext},
runtime::Runtime,
};
use super::components::Component;
#[derive(Default)]
pub struct ComponentRegistry<T> {
inner: HashMap<String, Arc<dyn Component<T>>>,
}
impl<T> ComponentRegistry<T>
where
T: Send + Sync + 'static,
{
pub fn new() -> Self {
Self {
inner: Default::default(),
}
}
pub fn register(&self, id: impl ToString, component: Arc<dyn Component<T>>) {
self.inner.upsert(id.to_string(), component);
}
pub fn unregister(&self, id: impl ToString) {
self.inner.remove(&id.to_string());
}
pub async fn execute(
&self,
event: &InteractionCreate,
rt: Arc<Runtime<T>>,
) -> Result<(), InteractionError> {
if let Some(data) = &event.data {
match data {
InteractionData::MessageComponent(data) => {
if let Some(component) = self.inner.get_async(&data.custom_id).await {
let prefixes = rt
.get_prefixes(
event.guild_id.map(|id| id.get()),
event.author_id().map(|id| id.get()),
)
.await;
let prefix = prefixes
.first()
.ok_or(InteractionError::PrefixesVectorEmpty)?;
component
.execute(InteractionContext::new(
event.clone(),
rt.clone(),
prefix.to_string(),
))
.await
} else {
Err(InteractionError::InteractionNotFound)
}
}
_ => Err(InteractionError::InteractionTypeUnsent),
}
} else {
Err(InteractionError::InteractionTypeUnsent)
}
}
}