teloxide 0.11.0

An elegant Telegram bots framework for Rust
Documentation
#![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.")
            ),)*
        }
    }
}

// May be expanded in the future.
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
            ),)*
        }
    }
}

// May be expanded in the future.
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),
}