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 { inner: HashMap>>, } impl ComponentRegistry where T: Send + Sync + 'static, { pub fn new() -> Self { Self { inner: Default::default(), } } pub fn register(&self, id: impl ToString, component: Arc>) { 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>, ) -> 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) } } }