feat: fix the command handler to reveal more data about the interaction

This commit is contained in:
2026-03-27 01:35:29 -04:00
parent d9e0801ec9
commit 3439bf9699
8 changed files with 70 additions and 55 deletions

View File

@@ -1,14 +1,8 @@
use std::{
ffi::{CStr, CString},
fmt::Debug,
sync::Arc,
};
use std::{fmt::Debug, sync::Arc};
use blart::TreeMap;
use futures::future::BoxFuture;
use twilight_model::application::{
command::Command, interaction::application_command::CommandData,
};
use patricia_tree::StringPatriciaMap;
use twilight_model::application::{command::Command, interaction::Interaction};
use crate::VCs;
@@ -22,14 +16,14 @@ pub struct State {
}
type Return = ();
type BoxedHandler = Box<dyn Fn(State, CommandData) -> BoxFuture<'static, Return>>;
type BoxedHandler = Box<dyn Fn(State, Interaction) -> BoxFuture<'static, Return>>;
fn box_handler<Handler, Fut>(handler: Handler) -> BoxedHandler
where
Fut: Future<Output = Return> + Send + 'static,
Handler: Fn(State, CommandData) -> Fut + 'static,
Handler: Fn(State, Interaction) -> Fut + 'static,
{
Box::new(move |state, command_data| Box::pin(handler(state, command_data)))
Box::new(move |state, interaction| Box::pin(handler(state, interaction)))
}
pub fn all() -> Vec<(&'static Command, BoxedHandler)> {
@@ -42,32 +36,31 @@ pub fn all() -> Vec<(&'static Command, BoxedHandler)> {
#[derive(Default)]
pub struct Router {
map: TreeMap<CString, BoxedHandler>,
map: StringPatriciaMap<BoxedHandler>,
}
impl Router {
fn add_route<'s, 'a, Fut, Handler>(&'s mut self, name: &'a str, handler: Handler)
where
Fut: Future<Output = Return> + Send + 'static,
Handler: Fn(State, CommandData) -> Fut + 'static,
Handler: Fn(State, Interaction) -> Fut + 'static,
{
self.add_route_already_boxed(name, box_handler(handler));
}
fn add_route_already_boxed<'s, 'a>(&'s mut self, name: &'a str, boxed_handler: BoxedHandler) {
self.map.insert(name.parse().unwrap(), boxed_handler);
self.map.insert(name, boxed_handler);
}
pub async fn handle(&self, state: State, command_data: CommandData) -> Return {
let name = &command_data.name;
let key = CStr::from_bytes_with_nul(name.as_bytes()).unwrap();
pub async fn handle(
&self,
state: State,
command_name: &str,
interaction: Interaction,
) -> Option<Return> {
let handler = self.map.get(command_name)?;
let handler = self
.map
.get(key)
.expect("asked to handle an inexistent command");
handler(state, command_data).await
Some(handler(state, interaction).await)
}
}