1use crate::{base::extract::FromEvent, event::BotEvent};
2use async_trait::async_trait;
3use std::{convert::Infallible, future::Future, ops::FromResidual};
4
5use super::context::BotContext;
6
7pub enum HandlerControl {
8 Skip,
9 Continue,
10 Block,
11}
12
13impl<E> FromResidual<Result<Infallible, E>> for HandlerControl {
14 fn from_residual(residual: Result<Infallible, E>) -> Self {
15 match residual {
16 Err(_) => HandlerControl::Skip,
17 }
18 }
19}
20
21impl FromResidual<Option<Infallible>> for HandlerControl {
22 fn from_residual(residual: Option<Infallible>) -> Self {
23 match residual {
24 None => HandlerControl::Skip,
25 }
26 }
27}
28
29#[async_trait]
30pub trait Handler<T> {
31 async fn handle(&self, context: BotContext, event: BotEvent) -> HandlerControl;
32}
33
34macro_rules! impl_handler {
35 ([$($ty:ident),*]) => {
36 #[allow(unused_variables, unused_mut,unused_parens,non_snake_case)]
37 #[async_trait]
38 impl<F,Fut, $($ty),*> Handler<($($ty),*)> for F
39 where
40 F: Fn($($ty),*) -> Fut + Send + Sync + 'static,
41 Fut: Future<Output = HandlerControl> + Send + 'static,
42 $($ty: FromEvent+Send),*
43 {
44 async fn handle(&self, context: BotContext, event: BotEvent) -> HandlerControl {
45 match ($($ty::from_event(context.clone(), event.clone()).await,)*) {
46 ($(Some($ty),)*) => self($($ty),*).await,
47 _ => HandlerControl::Skip,
48 }
49 }
50 }
51 };
52}
53
54#[async_trait]
55pub(crate) trait ErasedHandler: Send + Sync {
56 async fn call(&self, context: BotContext, event: BotEvent) -> HandlerControl;
57}
58
59pub(crate) struct HWrapped<T, H> {
60 pub handler: H,
61 pub _phantom: std::marker::PhantomData<T>,
62}
63
64#[async_trait]
65impl<H, T> ErasedHandler for HWrapped<T, H>
66where
67 H: Handler<T> + Send + Sync + 'static,
68 T: Send + Sync + 'static,
69{
70 async fn call(&self, context: BotContext, event: BotEvent) -> HandlerControl {
71 self.handler.handle(context, event).await
72 }
73}
74
75macro_rules! all_tuples {
76 ($macro:ident) => {
77 $macro!([T1]);
78 $macro!([T1, T2]);
79 $macro!([T1, T2, T3]);
80 $macro!([T1, T2, T3, T4]);
81 $macro!([T1, T2, T3, T4, T5]);
82 $macro!([T1, T2, T3, T4, T5, T6]);
83 $macro!([T1, T2, T3, T4, T5, T6, T7]);
84 $macro!([T1, T2, T3, T4, T5, T6, T7, T8]);
85 $macro!([T1, T2, T3, T4, T5, T6, T7, T8, T9]);
86 $macro!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]);
87 $macro!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]);
88 $macro!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]);
89 $macro!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]);
90 $macro!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]);
91 $macro!([
92 T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15
93 ]);
94 };
95}
96
97all_tuples!(impl_handler);