mirror of
https://github.com/teloxide/teloxide.git
synced 2025-01-06 10:44:25 +01:00
Rework handlers (failing now)
This commit is contained in:
parent
ab8dae9213
commit
e6bf25b3bf
4 changed files with 203 additions and 184 deletions
|
@ -2,19 +2,24 @@ use crate::{
|
||||||
dispatching::{
|
dispatching::{
|
||||||
error_handlers::ErrorHandler, update_listeners,
|
error_handlers::ErrorHandler, update_listeners,
|
||||||
update_listeners::UpdateListener, CtxHandler, DispatcherHandlerCtx,
|
update_listeners::UpdateListener, CtxHandler, DispatcherHandlerCtx,
|
||||||
LoggingErrorHandler, Middleware,
|
DispatcherHandlerResult, LoggingErrorHandler,
|
||||||
},
|
},
|
||||||
types::{
|
types::{
|
||||||
CallbackQuery, ChosenInlineResult, InlineQuery, Message, Poll,
|
CallbackQuery, ChosenInlineResult, InlineQuery, Message, Poll,
|
||||||
PreCheckoutQuery, ShippingQuery, Update, UpdateKind,
|
PollAnswer, PreCheckoutQuery, ShippingQuery, Update, UpdateKind,
|
||||||
},
|
},
|
||||||
Bot,
|
Bot,
|
||||||
};
|
};
|
||||||
use futures::{stream, StreamExt};
|
use futures::{stream, StreamExt};
|
||||||
use std::{fmt::Debug, sync::Arc};
|
use std::{fmt::Debug, future::Future, sync::Arc};
|
||||||
|
|
||||||
type H<'a, Upd, HandlerE> = Option<
|
type Handlers<'a, Upd, HandlerE> = Vec<
|
||||||
Box<dyn CtxHandler<DispatcherHandlerCtx<Upd>, Result<(), HandlerE>> + 'a>,
|
Box<
|
||||||
|
dyn CtxHandler<
|
||||||
|
DispatcherHandlerCtx<Upd>,
|
||||||
|
DispatcherHandlerResult<Upd, HandlerE>,
|
||||||
|
> + 'a,
|
||||||
|
>,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
/// One dispatcher to rule them all.
|
/// One dispatcher to rule them all.
|
||||||
|
@ -24,20 +29,20 @@ type H<'a, Upd, HandlerE> = Option<
|
||||||
pub struct Dispatcher<'a, HandlerE> {
|
pub struct Dispatcher<'a, HandlerE> {
|
||||||
bot: Arc<Bot>,
|
bot: Arc<Bot>,
|
||||||
|
|
||||||
middlewares: Vec<Box<dyn Middleware<Update> + 'a>>,
|
|
||||||
|
|
||||||
handlers_error_handler: Box<dyn ErrorHandler<HandlerE> + 'a>,
|
handlers_error_handler: Box<dyn ErrorHandler<HandlerE> + 'a>,
|
||||||
|
|
||||||
message_handler: H<'a, Message, HandlerE>,
|
update_handlers: Handlers<'a, Update, HandlerE>,
|
||||||
edited_message_handler: H<'a, Message, HandlerE>,
|
message_handlers: Handlers<'a, Message, HandlerE>,
|
||||||
channel_post_handler: H<'a, Message, HandlerE>,
|
edited_message_handlers: Handlers<'a, Message, HandlerE>,
|
||||||
edited_channel_post_handler: H<'a, Message, HandlerE>,
|
channel_post_handlers: Handlers<'a, Message, HandlerE>,
|
||||||
inline_query_handler: H<'a, InlineQuery, HandlerE>,
|
edited_channel_post_handlers: Handlers<'a, Message, HandlerE>,
|
||||||
chosen_inline_result_handler: H<'a, ChosenInlineResult, HandlerE>,
|
inline_query_handlers: Handlers<'a, InlineQuery, HandlerE>,
|
||||||
callback_query_handler: H<'a, CallbackQuery, HandlerE>,
|
chosen_inline_result_handlers: Handlers<'a, ChosenInlineResult, HandlerE>,
|
||||||
shipping_query_handler: H<'a, ShippingQuery, HandlerE>,
|
callback_query_handlers: Handlers<'a, CallbackQuery, HandlerE>,
|
||||||
pre_checkout_query_handler: H<'a, PreCheckoutQuery, HandlerE>,
|
shipping_query_handlers: Handlers<'a, ShippingQuery, HandlerE>,
|
||||||
poll_handler: H<'a, Poll, HandlerE>,
|
pre_checkout_query_handlers: Handlers<'a, PreCheckoutQuery, HandlerE>,
|
||||||
|
poll_handlers: Handlers<'a, Poll, HandlerE>,
|
||||||
|
poll_answer_handlers: Handlers<'a, PollAnswer, HandlerE>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, HandlerE> Dispatcher<'a, HandlerE>
|
impl<'a, HandlerE> Dispatcher<'a, HandlerE>
|
||||||
|
@ -49,37 +54,24 @@ where
|
||||||
pub fn new(bot: Bot) -> Self {
|
pub fn new(bot: Bot) -> Self {
|
||||||
Self {
|
Self {
|
||||||
bot: Arc::new(bot),
|
bot: Arc::new(bot),
|
||||||
middlewares: Vec::new(),
|
|
||||||
handlers_error_handler: Box::new(LoggingErrorHandler::new(
|
handlers_error_handler: Box::new(LoggingErrorHandler::new(
|
||||||
"An error from a Dispatcher's handler",
|
"An error from a Dispatcher's handler",
|
||||||
)),
|
)),
|
||||||
message_handler: None,
|
update_handlers: Vec::new(),
|
||||||
edited_message_handler: None,
|
message_handlers: Vec::new(),
|
||||||
channel_post_handler: None,
|
edited_message_handlers: Vec::new(),
|
||||||
edited_channel_post_handler: None,
|
channel_post_handlers: Vec::new(),
|
||||||
inline_query_handler: None,
|
edited_channel_post_handlers: Vec::new(),
|
||||||
chosen_inline_result_handler: None,
|
inline_query_handlers: Vec::new(),
|
||||||
callback_query_handler: None,
|
chosen_inline_result_handlers: Vec::new(),
|
||||||
shipping_query_handler: None,
|
callback_query_handlers: Vec::new(),
|
||||||
pre_checkout_query_handler: None,
|
shipping_query_handlers: Vec::new(),
|
||||||
poll_handler: None,
|
pre_checkout_query_handlers: Vec::new(),
|
||||||
|
poll_handlers: Vec::new(),
|
||||||
|
poll_answer_handlers: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Appends a middleware.
|
|
||||||
///
|
|
||||||
/// If a middleware has returned `None`, an update will not be handled by a
|
|
||||||
/// next middleware or an appropriate handler (if it's the last middleware).
|
|
||||||
/// Otherwise, an update in `Some(update)` is passed further.
|
|
||||||
#[must_use]
|
|
||||||
pub fn middleware<M>(mut self, val: M) -> Self
|
|
||||||
where
|
|
||||||
M: Middleware<Update> + 'a,
|
|
||||||
{
|
|
||||||
self.middlewares.push(Box::new(val));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Registers a handler of errors, produced by other handlers.
|
/// Registers a handler of errors, produced by other handlers.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn handlers_error_handler<T>(mut self, val: T) -> Self
|
pub fn handlers_error_handler<T>(mut self, val: T) -> Self
|
||||||
|
@ -90,106 +82,125 @@ where
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
/// Registers a single handler.
|
||||||
pub fn message_handler<H>(mut self, h: H) -> Self
|
fn register_handler<Upd, H, I>(
|
||||||
where
|
handlers: &mut Handlers<'a, Upd, HandlerE>,
|
||||||
H: CtxHandler<DispatcherHandlerCtx<Message>, Result<(), HandlerE>> + 'a,
|
h: H,
|
||||||
|
) where
|
||||||
|
H: CtxHandler<DispatcherHandlerCtx<Upd>, I> + 'a,
|
||||||
|
I: Into<DispatcherHandlerResult<Upd, HandlerE>>,
|
||||||
{
|
{
|
||||||
self.message_handler = Some(Box::new(h));
|
handlers
|
||||||
|
.push(Box::new(move |ctx| map_fut(h.handle_ctx(ctx), Into::into)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn message_handler<H, I>(mut self, h: H) -> Self
|
||||||
|
where
|
||||||
|
H: CtxHandler<DispatcherHandlerCtx<Message>, I> + 'a,
|
||||||
|
I: Into<DispatcherHandlerResult<Message, HandlerE>>,
|
||||||
|
{
|
||||||
|
Self::register_handler(&mut self.message_handlers, h);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn edited_message_handler<H>(mut self, h: H) -> Self
|
pub fn edited_message_handler<H, I>(mut self, h: H) -> Self
|
||||||
where
|
where
|
||||||
H: CtxHandler<DispatcherHandlerCtx<Message>, Result<(), HandlerE>> + 'a,
|
H: CtxHandler<DispatcherHandlerCtx<Message>, I> + 'a,
|
||||||
|
I: Into<DispatcherHandlerResult<Message, HandlerE>>,
|
||||||
{
|
{
|
||||||
self.edited_message_handler = Some(Box::new(h));
|
Self::register_handler(&mut self.edited_message_handlers, h);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn channel_post_handler<H>(mut self, h: H) -> Self
|
pub fn channel_post_handler<H, I>(mut self, h: H) -> Self
|
||||||
where
|
where
|
||||||
H: CtxHandler<DispatcherHandlerCtx<Message>, Result<(), HandlerE>> + 'a,
|
H: CtxHandler<DispatcherHandlerCtx<Message>, I> + 'a,
|
||||||
|
I: Into<DispatcherHandlerResult<Message, HandlerE>>,
|
||||||
{
|
{
|
||||||
self.channel_post_handler = Some(Box::new(h));
|
Self::register_handler(&mut self.channel_post_handlers, h);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn edited_channel_post_handler<H>(mut self, h: H) -> Self
|
pub fn edited_channel_post_handler<H, I>(mut self, h: H) -> Self
|
||||||
where
|
where
|
||||||
H: CtxHandler<DispatcherHandlerCtx<Message>, Result<(), HandlerE>> + 'a,
|
H: CtxHandler<DispatcherHandlerCtx<Message>, I> + 'a,
|
||||||
|
I: Into<DispatcherHandlerResult<Message, HandlerE>>,
|
||||||
{
|
{
|
||||||
self.edited_channel_post_handler = Some(Box::new(h));
|
Self::register_handler(&mut self.edited_channel_post_handlers, h);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn inline_query_handler<H>(mut self, h: H) -> Self
|
pub fn inline_query_handler<H, I>(mut self, h: H) -> Self
|
||||||
where
|
where
|
||||||
H: CtxHandler<DispatcherHandlerCtx<InlineQuery>, Result<(), HandlerE>>
|
H: CtxHandler<DispatcherHandlerCtx<InlineQuery>, I> + 'a,
|
||||||
+ 'a,
|
I: Into<DispatcherHandlerResult<InlineQuery, HandlerE>>,
|
||||||
{
|
{
|
||||||
self.inline_query_handler = Some(Box::new(h));
|
Self::register_handler(&mut self.inline_query_handlers, h);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn chosen_inline_result_handler<H>(mut self, h: H) -> Self
|
pub fn chosen_inline_result_handler<H, I>(mut self, h: H) -> Self
|
||||||
where
|
where
|
||||||
H: CtxHandler<
|
H: CtxHandler<DispatcherHandlerCtx<ChosenInlineResult>, I> + 'a,
|
||||||
DispatcherHandlerCtx<ChosenInlineResult>,
|
I: Into<DispatcherHandlerResult<ChosenInlineResult, HandlerE>>,
|
||||||
Result<(), HandlerE>,
|
|
||||||
> + 'a,
|
|
||||||
{
|
{
|
||||||
self.chosen_inline_result_handler = Some(Box::new(h));
|
Self::register_handler(&mut self.chosen_inline_result_handlers, h);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn callback_query_handler<H>(mut self, h: H) -> Self
|
pub fn callback_query_handler<H, I>(mut self, h: H) -> Self
|
||||||
where
|
where
|
||||||
H: CtxHandler<
|
H: CtxHandler<DispatcherHandlerCtx<CallbackQuery>, I> + 'a,
|
||||||
DispatcherHandlerCtx<CallbackQuery>,
|
I: Into<DispatcherHandlerResult<CallbackQuery, HandlerE>>,
|
||||||
Result<(), HandlerE>,
|
|
||||||
> + 'a,
|
|
||||||
{
|
{
|
||||||
self.callback_query_handler = Some(Box::new(h));
|
Self::register_handler(&mut self.callback_query_handlers, h);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn shipping_query_handler<H>(mut self, h: H) -> Self
|
pub fn shipping_query_handler<H, I>(mut self, h: H) -> Self
|
||||||
where
|
where
|
||||||
H: CtxHandler<
|
H: CtxHandler<DispatcherHandlerCtx<ShippingQuery>, I> + 'a,
|
||||||
DispatcherHandlerCtx<ShippingQuery>,
|
I: Into<DispatcherHandlerResult<ShippingQuery, HandlerE>>,
|
||||||
Result<(), HandlerE>,
|
|
||||||
> + 'a,
|
|
||||||
{
|
{
|
||||||
self.shipping_query_handler = Some(Box::new(h));
|
Self::register_handler(&mut self.shipping_query_handlers, h);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn pre_checkout_query_handler<H>(mut self, h: H) -> Self
|
pub fn pre_checkout_query_handler<H, I>(mut self, h: H) -> Self
|
||||||
where
|
where
|
||||||
H: CtxHandler<
|
H: CtxHandler<DispatcherHandlerCtx<PreCheckoutQuery>, I> + 'a,
|
||||||
DispatcherHandlerCtx<PreCheckoutQuery>,
|
I: Into<DispatcherHandlerResult<PreCheckoutQuery, HandlerE>>,
|
||||||
Result<(), HandlerE>,
|
|
||||||
> + 'a,
|
|
||||||
{
|
{
|
||||||
self.pre_checkout_query_handler = Some(Box::new(h));
|
Self::register_handler(&mut self.pre_checkout_query_handlers, h);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn poll_handler<H>(mut self, h: H) -> Self
|
pub fn poll_handler<H, I>(mut self, h: H) -> Self
|
||||||
where
|
where
|
||||||
H: CtxHandler<DispatcherHandlerCtx<Poll>, Result<(), HandlerE>> + 'a,
|
H: CtxHandler<DispatcherHandlerCtx<Poll>, I> + 'a,
|
||||||
|
I: Into<DispatcherHandlerResult<Poll, HandlerE>>,
|
||||||
{
|
{
|
||||||
self.poll_handler = Some(Box::new(h));
|
Self::register_handler(&mut self.poll_handlers, h);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn poll_answer_handler<H, I>(mut self, h: H) -> Self
|
||||||
|
where
|
||||||
|
H: CtxHandler<DispatcherHandlerCtx<PollAnswer>, I> + 'a,
|
||||||
|
I: Into<DispatcherHandlerResult<PollAnswer, HandlerE>>,
|
||||||
|
{
|
||||||
|
Self::register_handler(&mut self.poll_answer_handlers, h);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,59 +239,52 @@ where
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let update = stream::iter(&self.middlewares)
|
let update =
|
||||||
.fold(Some(update), |acc, middleware| async move {
|
match self.handle(&self.update_handlers, update).await {
|
||||||
// Option::and_then is not working here, because
|
Some(update) => update,
|
||||||
// Middleware::handle is asynchronous.
|
None => return,
|
||||||
match acc {
|
};
|
||||||
Some(update) => middleware.handle(update).await,
|
|
||||||
None => None,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
|
|
||||||
if let Some(update) = update {
|
|
||||||
match update.kind {
|
match update.kind {
|
||||||
UpdateKind::Message(message) => {
|
UpdateKind::Message(message) => {
|
||||||
self.handle(&self.message_handler, message).await
|
self.handle(&self.message_handlers, message).await;
|
||||||
}
|
}
|
||||||
UpdateKind::EditedMessage(message) => {
|
UpdateKind::EditedMessage(message) => {
|
||||||
self.handle(&self.edited_message_handler, message)
|
self.handle(&self.edited_message_handlers, message)
|
||||||
.await
|
.await;
|
||||||
}
|
}
|
||||||
UpdateKind::ChannelPost(post) => {
|
UpdateKind::ChannelPost(post) => {
|
||||||
self.handle(&self.channel_post_handler, post).await
|
self.handle(&self.channel_post_handlers, post).await;
|
||||||
}
|
}
|
||||||
UpdateKind::EditedChannelPost(post) => {
|
UpdateKind::EditedChannelPost(post) => {
|
||||||
self.handle(&self.edited_channel_post_handler, post)
|
self.handle(&self.edited_channel_post_handlers, post)
|
||||||
.await
|
.await;
|
||||||
}
|
}
|
||||||
UpdateKind::InlineQuery(query) => {
|
UpdateKind::InlineQuery(query) => {
|
||||||
self.handle(&self.inline_query_handler, query).await
|
self.handle(&self.inline_query_handlers, query).await;
|
||||||
}
|
}
|
||||||
UpdateKind::ChosenInlineResult(result) => {
|
UpdateKind::ChosenInlineResult(result) => {
|
||||||
self.handle(
|
self.handle(
|
||||||
&self.chosen_inline_result_handler,
|
&self.chosen_inline_result_handlers,
|
||||||
result,
|
result,
|
||||||
)
|
)
|
||||||
.await
|
.await;
|
||||||
}
|
}
|
||||||
UpdateKind::CallbackQuery(query) => {
|
UpdateKind::CallbackQuery(query) => {
|
||||||
self.handle(&self.callback_query_handler, query)
|
self.handle(&self.callback_query_handlers, query).await;
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
UpdateKind::ShippingQuery(query) => {
|
UpdateKind::ShippingQuery(query) => {
|
||||||
self.handle(&self.shipping_query_handler, query)
|
self.handle(&self.shipping_query_handlers, query).await;
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
UpdateKind::PreCheckoutQuery(query) => {
|
UpdateKind::PreCheckoutQuery(query) => {
|
||||||
self.handle(&self.pre_checkout_query_handler, query)
|
self.handle(&self.pre_checkout_query_handlers, query)
|
||||||
.await
|
.await;
|
||||||
}
|
}
|
||||||
UpdateKind::Poll(poll) => {
|
UpdateKind::Poll(poll) => {
|
||||||
self.handle(&self.poll_handler, poll).await
|
self.handle(&self.poll_handlers, poll).await;
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
UpdateKind::PollAnswer(answer) => {
|
||||||
|
self.handle(&self.poll_answer_handlers, answer).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -288,17 +292,40 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handles a single update.
|
// Handles a single update.
|
||||||
async fn handle<Upd>(&self, handler: &H<'a, Upd, HandlerE>, update: Upd) {
|
#[allow(clippy::ptr_arg)]
|
||||||
if let Some(handler) = &handler {
|
async fn handle<Upd>(
|
||||||
if let Err(error) = handler
|
&self,
|
||||||
|
handlers: &Handlers<'a, Upd, HandlerE>,
|
||||||
|
update: Upd,
|
||||||
|
) -> Option<Upd> {
|
||||||
|
stream::iter(handlers)
|
||||||
|
.fold(Some(update), |acc, handler| async move {
|
||||||
|
// Option::and_then is not working here, because
|
||||||
|
// Middleware::handle is asynchronous.
|
||||||
|
match acc {
|
||||||
|
Some(update) => {
|
||||||
|
let DispatcherHandlerResult { next, result } = handler
|
||||||
.handle_ctx(DispatcherHandlerCtx {
|
.handle_ctx(DispatcherHandlerCtx {
|
||||||
bot: Arc::clone(&self.bot),
|
bot: Arc::clone(&self.bot),
|
||||||
update,
|
update,
|
||||||
})
|
})
|
||||||
|
.await;
|
||||||
|
|
||||||
|
if let Err(error) = result {
|
||||||
|
self.handlers_error_handler
|
||||||
|
.handle_error(error)
|
||||||
.await
|
.await
|
||||||
{
|
|
||||||
self.handlers_error_handler.handle_error(error).await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
next
|
||||||
}
|
}
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn map_fut<T, U>(fut: impl Future<Output = T>, f: impl Fn(T) -> U) -> U {
|
||||||
|
f(fut.await)
|
||||||
|
}
|
||||||
|
|
23
src/dispatching/dispatcher_handler_result.rs
Normal file
23
src/dispatching/dispatcher_handler_result.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/// A result of a handler in [`Dispatcher`].
|
||||||
|
///
|
||||||
|
/// See [the module-level documentation for the design
|
||||||
|
/// overview](crate::dispatching).
|
||||||
|
///
|
||||||
|
/// [`Dispatcher`]: crate::dispatching::Dispatcher
|
||||||
|
pub struct DispatcherHandlerResult<Upd, E> {
|
||||||
|
next: Option<Upd>,
|
||||||
|
result: Result<(), E>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Upd, E> DispatcherHandlerResult<Upd, E> {
|
||||||
|
/// Creates new `DispatcherHandlerResult`.
|
||||||
|
pub fn new(next: Option<Upd>, result: Result<(), E>) -> Self {
|
||||||
|
Self { next, result }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Upd, E> From<Result<(), E>> for DispatcherHandlerResult<Upd, E> {
|
||||||
|
fn from(result: Result<(), E>) -> Self {
|
||||||
|
Self::new(None, result)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,31 +0,0 @@
|
||||||
use std::{future::Future, pin::Pin};
|
|
||||||
|
|
||||||
/// An asynchronous middleware.
|
|
||||||
///
|
|
||||||
/// See [the module-level documentation for the design
|
|
||||||
/// overview](crate::dispatching).
|
|
||||||
pub trait Middleware<T> {
|
|
||||||
#[must_use]
|
|
||||||
fn handle<'a>(
|
|
||||||
&'a self,
|
|
||||||
val: T,
|
|
||||||
) -> Pin<Box<dyn Future<Output = Option<T>> + 'a>>
|
|
||||||
where
|
|
||||||
T: 'a;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, F, Fut> Middleware<T> for F
|
|
||||||
where
|
|
||||||
F: Fn(T) -> Fut,
|
|
||||||
Fut: Future<Output = Option<T>>,
|
|
||||||
{
|
|
||||||
fn handle<'a>(
|
|
||||||
&'a self,
|
|
||||||
val: T,
|
|
||||||
) -> Pin<Box<dyn Future<Output = Fut::Output> + 'a>>
|
|
||||||
where
|
|
||||||
T: 'a,
|
|
||||||
{
|
|
||||||
Box::pin(async move { self(val).await })
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -45,15 +45,15 @@ mod ctx_handlers;
|
||||||
pub mod dialogue;
|
pub mod dialogue;
|
||||||
mod dispatcher;
|
mod dispatcher;
|
||||||
mod dispatcher_handler_ctx;
|
mod dispatcher_handler_ctx;
|
||||||
|
mod dispatcher_handler_result;
|
||||||
mod error_handlers;
|
mod error_handlers;
|
||||||
mod middleware;
|
|
||||||
pub mod update_listeners;
|
pub mod update_listeners;
|
||||||
|
|
||||||
pub use ctx_handlers::CtxHandler;
|
pub use ctx_handlers::CtxHandler;
|
||||||
pub use dispatcher::Dispatcher;
|
pub use dispatcher::Dispatcher;
|
||||||
pub use dispatcher_handler_ctx::DispatcherHandlerCtx;
|
pub use dispatcher_handler_ctx::DispatcherHandlerCtx;
|
||||||
|
pub use dispatcher_handler_result::DispatcherHandlerResult;
|
||||||
pub use error_handlers::{
|
pub use error_handlers::{
|
||||||
ErrorHandler, IgnoringErrorHandler, IgnoringErrorHandlerSafe,
|
ErrorHandler, IgnoringErrorHandler, IgnoringErrorHandlerSafe,
|
||||||
LoggingErrorHandler,
|
LoggingErrorHandler,
|
||||||
};
|
};
|
||||||
pub use middleware::Middleware;
|
|
||||||
|
|
Loading…
Reference in a new issue