Extend the middlewares API

This commit is contained in:
Temirkhan Myrzamadi 2020-02-07 06:20:14 +06:00
parent b064b85d37
commit 2785c892c0
4 changed files with 86 additions and 86 deletions

View file

@ -67,6 +67,10 @@ where
}
/// 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
@ -225,44 +229,57 @@ where
};
let update = stream::iter(&self.middlewares)
.fold(update, |acc, middleware| async move {
middleware.handle(acc).await
.fold(Some(update), |acc, middleware| async move {
// Option::and_then is not working here, because
// Middleware::handle is asynchronous.
match acc {
Some(update) => middleware.handle(update).await,
None => None,
}
})
.await;
match update.kind {
UpdateKind::Message(message) => {
self.handle(&self.message_handler, message).await
}
UpdateKind::EditedMessage(message) => {
self.handle(&self.edited_message_handler, message).await
}
UpdateKind::ChannelPost(post) => {
self.handle(&self.channel_post_handler, post).await
}
UpdateKind::EditedChannelPost(post) => {
self.handle(&self.edited_channel_post_handler, post)
if let Some(update) = update {
match update.kind {
UpdateKind::Message(message) => {
self.handle(&self.message_handler, message).await
}
UpdateKind::EditedMessage(message) => {
self.handle(&self.edited_message_handler, message)
.await
}
UpdateKind::ChannelPost(post) => {
self.handle(&self.channel_post_handler, post).await
}
UpdateKind::EditedChannelPost(post) => {
self.handle(&self.edited_channel_post_handler, post)
.await
}
UpdateKind::InlineQuery(query) => {
self.handle(&self.inline_query_handler, query).await
}
UpdateKind::ChosenInlineResult(result) => {
self.handle(
&self.chosen_inline_result_handler,
result,
)
.await
}
UpdateKind::InlineQuery(query) => {
self.handle(&self.inline_query_handler, query).await
}
UpdateKind::ChosenInlineResult(result) => {
self.handle(&self.chosen_inline_result_handler, result)
.await
}
UpdateKind::CallbackQuery(query) => {
self.handle(&self.callback_query_handler, query).await
}
UpdateKind::ShippingQuery(query) => {
self.handle(&self.shipping_query_handler, query).await
}
UpdateKind::PreCheckoutQuery(query) => {
self.handle(&self.pre_checkout_query_handler, query)
.await
}
UpdateKind::Poll(poll) => {
self.handle(&self.poll_handler, poll).await
}
UpdateKind::CallbackQuery(query) => {
self.handle(&self.callback_query_handler, query)
.await
}
UpdateKind::ShippingQuery(query) => {
self.handle(&self.shipping_query_handler, query)
.await
}
UpdateKind::PreCheckoutQuery(query) => {
self.handle(&self.pre_checkout_query_handler, query)
.await
}
UpdateKind::Poll(poll) => {
self.handle(&self.poll_handler, poll).await
}
}
}
})

View file

@ -6,7 +6,10 @@ use std::{future::Future, pin::Pin};
/// overview](crate::dispatching).
pub trait Middleware<T> {
#[must_use]
fn handle<'a>(&'a self, val: T) -> Pin<Box<dyn Future<Output = T> + 'a>>
fn handle<'a>(
&'a self,
val: T,
) -> Pin<Box<dyn Future<Output = Option<T>> + 'a>>
where
T: 'a;
}
@ -14,9 +17,12 @@ pub trait Middleware<T> {
impl<T, F, Fut> Middleware<T> for F
where
F: Fn(T) -> Fut,
Fut: Future<Output = T>,
Fut: Future<Output = Option<T>>,
{
fn handle<'a>(&'a self, val: T) -> Pin<Box<dyn Future<Output = T> + 'a>>
fn handle<'a>(
&'a self,
val: T,
) -> Pin<Box<dyn Future<Output = Fut::Output> + 'a>>
where
T: 'a,
{

View file

@ -26,10 +26,8 @@
//! // Setup logging here...
//!
//! Dispatcher::new(Bot::new("MyAwesomeToken"))
//! .message_handler(|ctx: DispatcherHandlerCtx<Message>| {
//! async move {
//! ctx.answer("pong").send().await?;
//! }
//! .message_handler(|ctx: DispatcherHandlerCtx<Message>| async move {
//! ctx.answer("pong").send().await?;
//! })
//! .dispatch()
//! .await;

View file

@ -2,7 +2,10 @@
use serde::{Deserialize, Serialize};
use crate::types::{CallbackQuery, ChosenInlineResult, InlineQuery, Message, Poll, PreCheckoutQuery, ShippingQuery, User, Sender, Chat};
use crate::types::{
CallbackQuery, Chat, ChosenInlineResult, InlineQuery, Message, Poll,
PreCheckoutQuery, Sender, ShippingQuery, User,
};
/// This [object] represents an incoming update.
///
@ -73,55 +76,31 @@ pub enum UpdateKind {
impl Update {
pub fn user(&self) -> Option<&User> {
match &self.kind {
UpdateKind::Message(m) => {
match m.from() {
Some(Sender::User(user)) => Some(user),
_ => None,
}
}
UpdateKind::EditedMessage(m) => {
match m.from() {
Some(Sender::User(user)) => Some(user),
_ => None,
}
}
UpdateKind::CallbackQuery(query) => {
Some(&query.from)
}
UpdateKind::ChosenInlineResult(chosen) => {
Some(&chosen.from)
}
UpdateKind::InlineQuery(query) => {
Some(&query.from)
}
UpdateKind::ShippingQuery(query) => {
Some(&query.from)
}
UpdateKind::PreCheckoutQuery(query) => {
Some(&query.from)
}
_ => None
UpdateKind::Message(m) => match m.from() {
Some(Sender::User(user)) => Some(user),
_ => None,
},
UpdateKind::EditedMessage(m) => match m.from() {
Some(Sender::User(user)) => Some(user),
_ => None,
},
UpdateKind::CallbackQuery(query) => Some(&query.from),
UpdateKind::ChosenInlineResult(chosen) => Some(&chosen.from),
UpdateKind::InlineQuery(query) => Some(&query.from),
UpdateKind::ShippingQuery(query) => Some(&query.from),
UpdateKind::PreCheckoutQuery(query) => Some(&query.from),
_ => None,
}
}
pub fn chat(&self) -> Option<&Chat> {
match &self.kind {
UpdateKind::Message(m) => {
Some(&m.chat)
}
UpdateKind::EditedMessage(m) => {
Some(&m.chat)
}
UpdateKind::ChannelPost(p) => {
Some(&p.chat)
}
UpdateKind::EditedChannelPost(p) => {
Some(&p.chat)
}
UpdateKind::CallbackQuery(q) => {
Some(&q.message.as_ref()?.chat)
}
_ => None
UpdateKind::Message(m) => Some(&m.chat),
UpdateKind::EditedMessage(m) => Some(&m.chat),
UpdateKind::ChannelPost(p) => Some(&p.chat),
UpdateKind::EditedChannelPost(p) => Some(&p.chat),
UpdateKind::CallbackQuery(q) => Some(&q.message.as_ref()?.chat),
_ => None,
}
}
}