1use std::future::Future;
2use std::pin::Pin;
3use std::sync::Arc;
4
5use async_trait::async_trait;
6
7use crate::context::Context;
8use crate::error::BotResult;
9
10pub type HandlerFuture = Pin<Box<dyn Future<Output = BotResult<()>> + Send>>;
12
13#[async_trait]
19pub trait Handler: Send + Sync + 'static {
20 async fn handle(&self, ctx: Context) -> BotResult<()>;
22}
23
24pub type BoxHandler = Arc<dyn Handler>;
26
27pub struct HandlerFn<F> {
29 f: F,
30}
31
32impl<F, Fut> HandlerFn<F>
33where
34 F: Fn(Context) -> Fut + Send + Sync + 'static,
35 Fut: Future<Output = BotResult<()>> + Send + 'static,
36{
37 pub fn new(f: F) -> Self {
39 Self { f }
40 }
41}
42
43#[async_trait]
44impl<F, Fut> Handler for HandlerFn<F>
45where
46 F: Fn(Context) -> Fut + Send + Sync + 'static,
47 Fut: Future<Output = BotResult<()>> + Send + 'static,
48{
49 async fn handle(&self, ctx: Context) -> BotResult<()> {
50 (self.f)(ctx).await
51 }
52}
53
54pub fn handler_fn<F, Fut>(f: F) -> BoxHandler
67where
68 F: Fn(Context) -> Fut + Send + Sync + 'static,
69 Fut: Future<Output = BotResult<()>> + Send + 'static,
70{
71 Arc::new(HandlerFn::new(f))
72}
73
74pub struct LoggingHandler {
76 inner: BoxHandler,
77}
78
79impl LoggingHandler {
80 pub fn wrap(inner: BoxHandler) -> BoxHandler {
83 Arc::new(Self { inner })
84 }
85}
86
87#[async_trait]
88impl Handler for LoggingHandler {
89 async fn handle(&self, ctx: Context) -> BotResult<()> {
90 let update_id = ctx.update_id();
91 if let Err(e) = self.inner.handle(ctx).await {
92 tracing::error!("Handler error on update {}: {}", update_id, e);
93 }
94 Ok(())
95 }
96}
97
98#[async_trait]
101impl Handler for std::sync::Arc<dyn Handler> {
102 async fn handle(&self, ctx: Context) -> BotResult<()> {
103 (**self).handle(ctx).await
104 }
105}