feat: improve transparency of the join command
This commit is contained in:
@@ -1,88 +1,93 @@
|
||||
use std::{fmt::Debug, sync::Arc};
|
||||
|
||||
use futures::future::BoxFuture;
|
||||
use patricia_tree::StringPatriciaMap;
|
||||
use songbird::Songbird;
|
||||
use twilight_model::application::{command::Command, interaction::Interaction};
|
||||
|
||||
use crate::VCs;
|
||||
|
||||
mod join;
|
||||
mod leave;
|
||||
mod opt_out;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct State {
|
||||
pub vcs: Arc<VCs>,
|
||||
pub songbird: Arc<Songbird>,
|
||||
}
|
||||
|
||||
type 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, Interaction) -> Fut + 'static,
|
||||
{
|
||||
Box::new(move |state, interaction| Box::pin(handler(state, interaction)))
|
||||
}
|
||||
|
||||
pub fn all() -> Vec<(&'static Command, BoxedHandler)> {
|
||||
vec![
|
||||
(&join::COMMAND, box_handler(join::handle)),
|
||||
(&leave::COMMAND, box_handler(leave::handle)),
|
||||
(&opt_out::COMMAND, box_handler(opt_out::handle)),
|
||||
]
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Router {
|
||||
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, 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, boxed_handler);
|
||||
}
|
||||
|
||||
pub async fn handle(
|
||||
&self,
|
||||
state: State,
|
||||
command_name: &str,
|
||||
interaction: Interaction,
|
||||
) -> Option<Return> {
|
||||
let handler = self.map.get(command_name)?;
|
||||
|
||||
Some(handler(state, interaction).await)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromIterator<(&'a Command, BoxedHandler)> for Router {
|
||||
#[inline]
|
||||
fn from_iter<T: IntoIterator<Item = (&'a Command, BoxedHandler)>>(iter: T) -> Self {
|
||||
let mut this = Self::default();
|
||||
|
||||
this.extend(iter);
|
||||
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Extend<(&'a Command, BoxedHandler)> for Router {
|
||||
#[inline]
|
||||
fn extend<T: IntoIterator<Item = (&'a Command, BoxedHandler)>>(&mut self, iter: T) {
|
||||
for (command, boxed_handler) in iter {
|
||||
let name = &command.name;
|
||||
self.add_route_already_boxed(name, boxed_handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
use std::{fmt::Debug, sync::Arc};
|
||||
|
||||
use futures::future::BoxFuture;
|
||||
use patricia_tree::StringPatriciaMap;
|
||||
use songbird::Songbird;
|
||||
use twilight_model::{
|
||||
application::{command::Command, interaction::Interaction},
|
||||
id::{Id, marker::ApplicationMarker},
|
||||
};
|
||||
|
||||
use crate::VCs;
|
||||
|
||||
mod join;
|
||||
mod leave;
|
||||
mod opt_out;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct State {
|
||||
pub discord_client: Arc<twilight_http::Client>,
|
||||
pub discord_application_id: Id<ApplicationMarker>,
|
||||
pub songbird: Arc<Songbird>,
|
||||
pub vcs: Arc<VCs>,
|
||||
}
|
||||
|
||||
type 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, Interaction) -> Fut + 'static,
|
||||
{
|
||||
Box::new(move |state, interaction| Box::pin(handler(state, interaction)))
|
||||
}
|
||||
|
||||
pub fn all() -> Vec<(&'static Command, BoxedHandler)> {
|
||||
vec![
|
||||
(&join::COMMAND, box_handler(join::handle)),
|
||||
(&leave::COMMAND, box_handler(leave::handle)),
|
||||
(&opt_out::COMMAND, box_handler(opt_out::handle)),
|
||||
]
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Router {
|
||||
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, 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, boxed_handler);
|
||||
}
|
||||
|
||||
pub async fn handle(
|
||||
&self,
|
||||
state: State,
|
||||
command_name: &str,
|
||||
interaction: Interaction,
|
||||
) -> Option<Return> {
|
||||
let handler = self.map.get(command_name)?;
|
||||
|
||||
Some(handler(state, interaction).await)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromIterator<(&'a Command, BoxedHandler)> for Router {
|
||||
#[inline]
|
||||
fn from_iter<T: IntoIterator<Item = (&'a Command, BoxedHandler)>>(iter: T) -> Self {
|
||||
let mut this = Self::default();
|
||||
|
||||
this.extend(iter);
|
||||
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Extend<(&'a Command, BoxedHandler)> for Router {
|
||||
#[inline]
|
||||
fn extend<T: IntoIterator<Item = (&'a Command, BoxedHandler)>>(&mut self, iter: T) {
|
||||
for (command, boxed_handler) in iter {
|
||||
let name = &command.name;
|
||||
self.add_route_already_boxed(name, boxed_handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user