Accept the handler as a parameter in Dispatcher::new

This commit is contained in:
Hirrolot 2022-01-23 20:58:55 +06:00
parent ad88db96b6
commit 7d6c374828
4 changed files with 39 additions and 53 deletions

View file

@ -5,7 +5,7 @@ use crate::{
},
error_handlers::{ErrorHandler, LoggingErrorHandler},
requests::Requester,
types::{AllowedUpdate, Update, UpdateKind},
types::{AllowedUpdate, Update},
};
use dptree::di::DependencyMap;
use futures::StreamExt;
@ -31,42 +31,19 @@ pub struct Dispatcher<R, Err> {
pub type UpdateHandler<Err> = dptree::Handler<'static, DependencyMap, Result<(), Err>>;
pub type DefaultHandler = dptree::Handler<'static, DependencyMap, (), Infallible>;
macro_rules! define_handlers {
($( ($func:ident, $update:ident) ,)*) => {
$(
#[must_use = "Call .dispatch() or .dispatch_with_listener() function to start dispatching."]
pub fn $func(mut self, make_handler: impl FnOnce(UpdateHandler<Err>) -> UpdateHandler<Err>) -> Self {
self.allowed_updates.insert(AllowedUpdate::$update);
Dispatcher { handler: self.handler.branch(make_handler(make_parser!($update))), ..self }
}
)*
}
}
macro_rules! make_parser {
($kind:ident) => {
dptree::filter_map(|upd: Update| async move {
match upd.kind {
UpdateKind::$kind(u) => Some(u),
_ => None,
}
})
};
}
impl<R, Err> Dispatcher<R, Err>
where
R: Clone + Send + Sync + 'static,
Err: Send + Sync + 'static,
{
pub fn new(requester: R) -> Self
pub fn new(requester: R, handler: UpdateHandler<Err>) -> Self
where
Err: Debug,
{
Dispatcher {
requester,
dependencies: DependencyMap::new(),
handler: dptree::entry(),
handler,
default_handler: dptree::endpoint(|update: Update| async move {
log::warn!("Unhandled update: {:?}", update)
}),

View file

@ -16,44 +16,49 @@ macro_rules! define_ext {
};
(@sig $func:ident, $arg_ty:ty) => {
fn $func<F, Fut>() -> Handler<'static, DependencyMap, Out>;
fn $func() -> Handler<'static, DependencyMap, Out>;
};
(@impl $for_ty:ty, $func:ident, $arg_ty:ty, $proj_fn:expr) => {
fn $func<F, Fut>() -> Handler<'static, DependencyMap, Out> {
fn $func() -> Handler<'static, DependencyMap, Out> {
dptree::filter_map(move |input: $for_ty| {
let result = $proj_fn(&input).map(ToOwned::to_owned);
async move { result }
async move { $proj_fn(input) }
})
}
};
}
macro_rules! to_owned_fn {
($fn_name:expr) => {
|x| $fn_name(&x).map(ToOwned::to_owned)
};
}
// May be expanded in the future.
define_ext! {
MessageFilterExt, Message =>
(filter_from, types::User, Message::from),
(filter_animation, types::Animation, Message::animation),
(filter_audio, types::Audio, Message::audio),
(filter_contact, types::Contact, Message::contact),
(filter_document, types::Document, Message::document),
(filter_location, types::Location, Message::location),
(filter_photo, [types::PhotoSize], Message::photo),
(filter_poll, types::Poll, Message::poll),
(filter_sticker, types::Sticker, Message::sticker),
(filter_text, str, Message::text),
(filter_reply_to_message, Message, Message::reply_to_message),
(filter_forward_from, types::ForwardedFrom, Message::forward_from),
(filter_new_chat_members, [types::User], Message::new_chat_members),
(filter_left_chat_member, types::User, Message::left_chat_member),
(filter_pinned, Message, Message::pinned_message),
(filter_dice, types::Dice, Message::dice),
(filter_from, types::User, to_owned_fn![Message::from]),
(filter_animation, types::Animation, to_owned_fn![Message::animation]),
(filter_audio, types::Audio, to_owned_fn![Message::audio]),
(filter_contact, types::Contact, to_owned_fn![Message::contact]),
(filter_document, types::Document, to_owned_fn![Message::document]),
(filter_location, types::Location, to_owned_fn![Message::location]),
(filter_photo, [types::PhotoSize], to_owned_fn![Message::photo]),
(filter_poll, types::Poll, to_owned_fn![Message::poll]),
(filter_sticker, types::Sticker, to_owned_fn![Message::sticker]),
(filter_text, str, to_owned_fn![Message::text]),
(filter_reply_to_message, Message, to_owned_fn![Message::reply_to_message]),
(filter_forward_from, types::ForwardedFrom, to_owned_fn![Message::forward_from]),
(filter_new_chat_members, [types::User], to_owned_fn![Message::new_chat_members]),
(filter_left_chat_member, types::User, to_owned_fn![Message::left_chat_member]),
(filter_pinned, Message, to_owned_fn![Message::pinned_message]),
(filter_dice, types::Dice, to_owned_fn![Message::dice]),
}
macro_rules! kind {
($kind:ident) => {
|update: &Update| match update.kind {
UpdateKind::$kind(x) => Some(&x),
|update: Update| match update.kind {
UpdateKind::$kind(x) => Some(x),
_ => None,
}
};

View file

@ -1,7 +1,8 @@
use crate::{
dispatching::{update_listeners, update_listeners::UpdateListener},
dispatching2::{handler_ext::HandlerExt, Dispatcher},
dispatching2::{Dispatcher, HandlerExt, UpdateFilterExt},
error_handlers::LoggingErrorHandler,
types::Update,
utils::command::BotCommand,
};
use dptree::di::{DependencyMap, Injectable};
@ -75,8 +76,10 @@ pub async fn commands_repl_with_listener<'a, R, Cmd, H, L, ListenerE, N, E, Args
{
let bot_name = bot_name.into();
let dispatcher = Dispatcher::new(requester)
.messages_handler(|h| h.add_command::<Cmd>(bot_name).branch(dptree::endpoint(handler)));
let dispatcher = Dispatcher::new(
requester,
Update::filter_message().add_command::<Cmd>(bot_name).branch(dptree::endpoint(handler)),
);
#[cfg(feature = "ctrlc_handler")]
let dispatcher = dispatcher.setup_ctrlc_handler();

View file

@ -1,7 +1,8 @@
use crate::{
dispatching::{update_listeners, update_listeners::UpdateListener},
dispatching2::Dispatcher,
dispatching2::{Dispatcher, UpdateFilterExt},
error_handlers::{LoggingErrorHandler, OnError},
types::Update,
};
use dptree::di::{DependencyMap, Injectable};
use std::fmt::Debug;
@ -63,7 +64,7 @@ pub async fn repl_with_listener<'a, R, H, E, L, ListenerE, Args>(
{
#[allow(unused_mut)]
let mut dispatcher =
Dispatcher::new(requester).messages_handler(|h| h.branch(dptree::endpoint(handler)));
Dispatcher::new(requester, Update::filter_message().branch(dptree::endpoint(handler)));
#[cfg(feature = "ctrlc_handler")]
let mut dispatcher = dispatcher.setup_ctrlc_handler();