#![allow(clippy::redundant_closure_call)]
use dptree::{di::DependencyMap, Handler};
use crate::{
dispatching::DpHandlerDescription,
types::{AllowedUpdate, Message, Update, UpdateKind},
};
macro_rules! define_ext {
($ext_name:ident, $for_ty:ty => $( ($func:ident, $proj_fn:expr, $fn_doc:expr $(, $Allowed:ident)? ) ,)*) => {
#[doc = concat!("Filter methods for [`", stringify!($for_ty), "`].")]
pub trait $ext_name<Out>: private::Sealed {
$( define_ext!(@sig $func, $fn_doc); )*
}
impl<Out> $ext_name<Out> for $for_ty
where
Out: Send + Sync + 'static,
{
$( define_ext!(@impl $for_ty, $func, $proj_fn $(, $Allowed )? ); )*
}
};
(@sig $func:ident, $fn_doc:expr) => {
#[doc = $fn_doc]
fn $func() -> Handler<'static, DependencyMap, Out, DpHandlerDescription>;
};
(@impl $for_ty:ty, $func:ident, $proj_fn:expr, $Allowed:ident) => {
fn $func() -> Handler<'static, DependencyMap, Out, DpHandlerDescription> {
dptree::filter_map_with_description(DpHandlerDescription::of(AllowedUpdate::$Allowed), move |input: $for_ty| {
$proj_fn(input)
})
}
};
(@impl $for_ty:ty, $func:ident, $proj_fn:expr) => {
fn $func() -> Handler<'static, DependencyMap, Out, DpHandlerDescription> {
dptree::filter_map(move |input: $for_ty| {
$proj_fn(input)
})
}
};
}
mod private {
use teloxide_core::types::{Message, Update};
pub trait Sealed {}
impl Sealed for Update {}
impl Sealed for Message {}
}
macro_rules! define_message_ext {
($( ($func:ident, $fn_name:path) ,)*) => {
define_ext! {
MessageFilterExt, Message =>
$((
$func,
(|x| $fn_name(&x).map(ToOwned::to_owned)),
concat!("Applies the [`", stringify!($fn_name), "`] filter.")
),)*
}
}
}
define_message_ext! {
(filter_from, Message::from),
(filter_animation, Message::animation),
(filter_audio, Message::audio),
(filter_contact, Message::contact),
(filter_document, Message::document),
(filter_location, Message::location),
(filter_photo, Message::photo),
(filter_poll, Message::poll),
(filter_sticker, Message::sticker),
(filter_text, Message::text),
(filter_reply_to_message, Message::reply_to_message),
(filter_forward_from, Message::forward_from),
(filter_new_chat_members, Message::new_chat_members),
(filter_left_chat_member, Message::left_chat_member),
(filter_pinned, Message::pinned_message),
(filter_dice, Message::dice),
}
macro_rules! define_update_ext {
($( ($func:ident, $kind:path, $Allowed:ident) ,)*) => {
define_ext! {
UpdateFilterExt, Update =>
$((
$func,
|update: Update| match update.kind {
$kind(x) => Some(x),
_ => None,
},
concat!("Filters out [`", stringify!($kind), "`] objects."),
$Allowed
),)*
}
}
}
define_update_ext! {
(filter_message, UpdateKind::Message, Message),
(filter_edited_message, UpdateKind::EditedMessage, EditedMessage),
(filter_channel_post, UpdateKind::ChannelPost, ChannelPost),
(filter_edited_channel_post, UpdateKind::EditedChannelPost, EditedChannelPost),
(filter_inline_query, UpdateKind::InlineQuery, InlineQuery),
(filter_chosen_inline_result, UpdateKind::ChosenInlineResult, ChosenInlineResult),
(filter_callback_query, UpdateKind::CallbackQuery, CallbackQuery),
(filter_shipping_query, UpdateKind::ShippingQuery, ShippingQuery),
(filter_pre_checkout_query, UpdateKind::PreCheckoutQuery, PreCheckoutQuery),
(filter_poll, UpdateKind::Poll, Poll),
(filter_poll_answer, UpdateKind::PollAnswer, PollAnswer),
(filter_my_chat_member, UpdateKind::MyChatMember, MyChatMember),
(filter_chat_member, UpdateKind::ChatMember, ChatMember),
}