Module tbot::compositors 
source · Expand description
Useful compositors for update handlers.
Let’s start with a simple example. You’re writing a bot, and its main
functionality is searching through something. In private chats, it’s enough
to send a text message to start searching; but in groups, it’s better to
search only when someone sent the /search command. Since you already
expected to have the same logic in different handlers, you wrote a generic
handler, search, and then registered it like this:
use std::sync::Arc;
use tbot::{Bot, contexts::fields::Text, prelude::*};
async fn search(context: Arc<impl Text>) {
    // ..
}
let mut bot = Bot::from_env("BOT_TOKEN").event_loop();
bot.text(|context| async move {
    if context.chat.kind.is_private() {
        search(context).await;
    }
});
bot.command("search", search);The text handler seems a bit too long just to filter out messages from
channels and groups. That’s where we can make use of our first compositor,
filter! It takes a predicate and a handler and returns its own handler.
If the predicate returns true, filter’s handler executes yours.
Here’s an example:
use tbot::{contexts::Text, compositors::filter};
bot.text(filter(
    |context: Arc<Text>| async move { context.chat.kind.is_private() },
    search,
));That looks better! But tbot already provides the predicate we just wrote
ourselves, so let’s use that:
use tbot::{compositors::filter, predicates::chat::is_private};
bot.text(filter(is_private, search));Great! Now you see how compositors make registering handlers easier.
filter isn’t the only compositor, you’ll find all of them in this
module.
Remember one thing though. Compositors add layers between the handler
and handler registers. If you’re going to use a closure for your handler,
type inference will fail and you’ll have to explicitly define context’s
type, as seen in the example with an inlined predicate above. That only
affects closures: using plain functions is fine even with generics, as seen
in the last example.
Modules
StatefulEventLoop.Functions
handler only if predicate returns true.predicate, and if it returned Some,
calls handler with that value.mapper, and then passes its return value to handler.