76 lines
2.2 KiB
Rust
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)
|
|
}
|
|
}
|
|
}
|