mirror of
https://github.com/teloxide/teloxide.git
synced 2025-01-24 09:16:12 +01:00
Merge pull request #79 from telebofr/handles_type
Simplify 'type Handlers = ...' (dispatchers/filter/mod.rs)
This commit is contained in:
commit
1df08f02c7
3 changed files with 75 additions and 66 deletions
|
@ -1,8 +1,4 @@
|
||||||
use std::{
|
use std::{convert::Infallible, future::Future, pin::Pin};
|
||||||
pin::Pin,
|
|
||||||
future::Future,
|
|
||||||
convert::Infallible,
|
|
||||||
};
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
||||||
|
@ -21,8 +17,7 @@ pub trait ErrorPolicy<E> {
|
||||||
/// # #[tokio::main]
|
/// # #[tokio::main]
|
||||||
/// # async fn main() {
|
/// # async fn main() {
|
||||||
/// use telebofr::dispatching::dispatchers::filter::error_policy::{
|
/// use telebofr::dispatching::dispatchers::filter::error_policy::{
|
||||||
/// ErrorPolicy,
|
/// ErrorPolicy, Ignore,
|
||||||
/// Ignore,
|
|
||||||
/// };
|
/// };
|
||||||
///
|
///
|
||||||
/// Ignore.handle_error(()).await;
|
/// Ignore.handle_error(()).await;
|
||||||
|
@ -39,11 +34,13 @@ where
|
||||||
{
|
{
|
||||||
async fn handle_error(&self, _: E)
|
async fn handle_error(&self, _: E)
|
||||||
where
|
where
|
||||||
E: 'async_trait
|
E: 'async_trait,
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Error policy that silently ignores all errors that can never happen (e.g.: [`!`] or [`Infallible`])
|
/// Error policy that silently ignores all errors that can never happen (e.g.:
|
||||||
|
/// [`!`] or [`Infallible`])
|
||||||
///
|
///
|
||||||
/// ## Examples
|
/// ## Examples
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -68,8 +65,7 @@ where
|
||||||
///
|
///
|
||||||
/// ```compile_fail
|
/// ```compile_fail
|
||||||
/// use telebofr::dispatching::dispatchers::filter::error_policy::{
|
/// use telebofr::dispatching::dispatchers::filter::error_policy::{
|
||||||
/// ErrorPolicy,
|
/// ErrorPolicy, IgnoreSafe,
|
||||||
/// IgnoreSafe,
|
|
||||||
/// };
|
/// };
|
||||||
///
|
///
|
||||||
/// IgnoreSafe.handle_error(0);
|
/// IgnoreSafe.handle_error(0);
|
||||||
|
@ -90,7 +86,7 @@ pub struct IgnoreSafe;
|
||||||
impl ErrorPolicy<!> for IgnoreSafe {
|
impl ErrorPolicy<!> for IgnoreSafe {
|
||||||
async fn handle_error(&self, never: !)
|
async fn handle_error(&self, never: !)
|
||||||
where
|
where
|
||||||
!: 'async_trait
|
!: 'async_trait,
|
||||||
{
|
{
|
||||||
never
|
never
|
||||||
}
|
}
|
||||||
|
@ -100,7 +96,7 @@ impl ErrorPolicy<!> for IgnoreSafe {
|
||||||
impl ErrorPolicy<Infallible> for IgnoreSafe {
|
impl ErrorPolicy<Infallible> for IgnoreSafe {
|
||||||
async fn handle_error(&self, inf: Infallible)
|
async fn handle_error(&self, inf: Infallible)
|
||||||
where
|
where
|
||||||
Infallible: 'async_trait
|
Infallible: 'async_trait,
|
||||||
{
|
{
|
||||||
match inf {}
|
match inf {}
|
||||||
}
|
}
|
||||||
|
@ -114,9 +110,7 @@ impl ErrorPolicy<Infallible> for IgnoreSafe {
|
||||||
/// # async fn main() {
|
/// # async fn main() {
|
||||||
/// use telebofr::dispatching::dispatchers::filter::error_policy::ErrorPolicy;
|
/// use telebofr::dispatching::dispatchers::filter::error_policy::ErrorPolicy;
|
||||||
///
|
///
|
||||||
/// let closure = |e: i32| async move {
|
/// let closure = |e: i32| async move { eprintln!("Error code{}", e) };
|
||||||
/// eprintln!("Error code{}", e)
|
|
||||||
/// };
|
|
||||||
///
|
///
|
||||||
/// closure.handle_error(404).await;
|
/// closure.handle_error(404).await;
|
||||||
/// # }
|
/// # }
|
||||||
|
@ -127,11 +121,14 @@ where
|
||||||
Fut: Future<Output = ()> + Send,
|
Fut: Future<Output = ()> + Send,
|
||||||
E: Send,
|
E: Send,
|
||||||
{
|
{
|
||||||
fn handle_error<'s, 'async_trait>(&'s self, error: E) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
|
fn handle_error<'s, 'async_trait>(
|
||||||
|
&'s self,
|
||||||
|
error: E,
|
||||||
|
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
|
||||||
where
|
where
|
||||||
's: 'async_trait,
|
's: 'async_trait,
|
||||||
Self: 'async_trait,
|
Self: 'async_trait,
|
||||||
E: 'async_trait
|
E: 'async_trait,
|
||||||
{
|
{
|
||||||
Box::pin(async move { self(error).await })
|
Box::pin(async move { self(error).await })
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,25 @@ use crate::{
|
||||||
|
|
||||||
pub mod error_policy;
|
pub mod error_policy;
|
||||||
|
|
||||||
type Handlers<'a, T, E> =
|
struct FilterAndHandler<'a, T, E> {
|
||||||
Vec<(Box<dyn Filter<T> + 'a>, Box<dyn Handler<'a, T, E> + 'a>)>;
|
filter: Box<dyn Filter<T> + 'a>,
|
||||||
|
handler: Box<dyn Handler<'a, T, E> + 'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T, E> FilterAndHandler<'a, T, E> {
|
||||||
|
fn new<F, H>(filter: F, handler: H) -> Self
|
||||||
|
where
|
||||||
|
F: Filter<T> + 'a,
|
||||||
|
H: Handler<'a, T, E> + 'a,
|
||||||
|
{
|
||||||
|
FilterAndHandler {
|
||||||
|
filter: Box::new(filter),
|
||||||
|
handler: Box::new(handler),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type FiltersAndHandlers<'a, T, E> = Vec<FilterAndHandler<'a, T, E>>;
|
||||||
|
|
||||||
/// Dispatcher that dispatches updates from telegram.
|
/// Dispatcher that dispatches updates from telegram.
|
||||||
///
|
///
|
||||||
|
@ -36,12 +53,14 @@ type Handlers<'a, T, E> =
|
||||||
/// use std::convert::Infallible;
|
/// use std::convert::Infallible;
|
||||||
///
|
///
|
||||||
/// use telebofr::{
|
/// use telebofr::{
|
||||||
/// Bot,
|
|
||||||
/// types::Message,
|
|
||||||
/// dispatching::{
|
/// dispatching::{
|
||||||
/// dispatchers::filter::{error_policy::ErrorPolicy, FilterDispatcher},
|
/// dispatchers::filter::{
|
||||||
|
/// error_policy::ErrorPolicy, FilterDispatcher,
|
||||||
|
/// },
|
||||||
/// updater::polling,
|
/// updater::polling,
|
||||||
/// },
|
/// },
|
||||||
|
/// types::Message,
|
||||||
|
/// Bot,
|
||||||
/// };
|
/// };
|
||||||
///
|
///
|
||||||
/// async fn handle_edited_message(mes: Message) {
|
/// async fn handle_edited_message(mes: Message) {
|
||||||
|
@ -67,16 +86,18 @@ type Handlers<'a, T, E> =
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [`std::fmt::Debug`]: std::fmt::Debug
|
/// [`std::fmt::Debug`]: std::fmt::Debug
|
||||||
/// [Custom error policy]: crate::dispatching::filter::error_policy::ErrorPolicy::Custom
|
/// [Custom error policy]:
|
||||||
/// [updater]: crate::dispatching::updater
|
/// crate::dispatching::filter::error_policy::ErrorPolicy::Custom [updater]:
|
||||||
|
/// crate::dispatching::updater
|
||||||
pub struct FilterDispatcher<'a, E, Ep> {
|
pub struct FilterDispatcher<'a, E, Ep> {
|
||||||
message_handlers: Handlers<'a, Message, E>,
|
message_handlers: FiltersAndHandlers<'a, Message, E>,
|
||||||
edited_message_handlers: Handlers<'a, Message, E>,
|
edited_message_handlers: FiltersAndHandlers<'a, Message, E>,
|
||||||
channel_post_handlers: Handlers<'a, Message, E>,
|
channel_post_handlers: FiltersAndHandlers<'a, Message, E>,
|
||||||
edited_channel_post_handlers: Handlers<'a, Message, E>,
|
edited_channel_post_handlers: FiltersAndHandlers<'a, Message, E>,
|
||||||
inline_query_handlers: Handlers<'a, (), E>,
|
inline_query_handlers: FiltersAndHandlers<'a, (), E>,
|
||||||
chosen_inline_result_handlers: Handlers<'a, ChosenInlineResult, E>,
|
chosen_inline_result_handlers:
|
||||||
callback_query_handlers: Handlers<'a, CallbackQuery, E>,
|
FiltersAndHandlers<'a, ChosenInlineResult, E>,
|
||||||
|
callback_query_handlers: FiltersAndHandlers<'a, CallbackQuery, E>,
|
||||||
error_policy: Ep,
|
error_policy: Ep,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +125,7 @@ where
|
||||||
H: Handler<'a, Message, E> + 'a,
|
H: Handler<'a, Message, E> + 'a,
|
||||||
{
|
{
|
||||||
self.message_handlers
|
self.message_handlers
|
||||||
.push((Box::new(filter), Box::new(handler)));
|
.push(FilterAndHandler::new(filter, handler));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +135,7 @@ where
|
||||||
H: Handler<'a, Message, E> + 'a,
|
H: Handler<'a, Message, E> + 'a,
|
||||||
{
|
{
|
||||||
self.edited_message_handlers
|
self.edited_message_handlers
|
||||||
.push((Box::new(filter), Box::new(handler)));
|
.push(FilterAndHandler::new(filter, handler));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +145,7 @@ where
|
||||||
H: Handler<'a, Message, E> + 'a,
|
H: Handler<'a, Message, E> + 'a,
|
||||||
{
|
{
|
||||||
self.channel_post_handlers
|
self.channel_post_handlers
|
||||||
.push((Box::new(filter), Box::new(handler)));
|
.push(FilterAndHandler::new(filter, handler));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +159,7 @@ where
|
||||||
H: Handler<'a, Message, E> + 'a,
|
H: Handler<'a, Message, E> + 'a,
|
||||||
{
|
{
|
||||||
self.edited_channel_post_handlers
|
self.edited_channel_post_handlers
|
||||||
.push((Box::new(filter), Box::new(handler)));
|
.push(FilterAndHandler::new(filter, handler));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +169,7 @@ where
|
||||||
H: Handler<'a, (), E> + 'a,
|
H: Handler<'a, (), E> + 'a,
|
||||||
{
|
{
|
||||||
self.inline_query_handlers
|
self.inline_query_handlers
|
||||||
.push((Box::new(filter), Box::new(handler)));
|
.push(FilterAndHandler::new(filter, handler));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +183,7 @@ where
|
||||||
H: Handler<'a, ChosenInlineResult, E> + 'a,
|
H: Handler<'a, ChosenInlineResult, E> + 'a,
|
||||||
{
|
{
|
||||||
self.chosen_inline_result_handlers
|
self.chosen_inline_result_handlers
|
||||||
.push((Box::new(filter), Box::new(handler)));
|
.push(FilterAndHandler::new(filter, handler));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +193,7 @@ where
|
||||||
H: Handler<'a, CallbackQuery, E> + 'a,
|
H: Handler<'a, CallbackQuery, E> + 'a,
|
||||||
{
|
{
|
||||||
self.callback_query_handlers
|
self.callback_query_handlers
|
||||||
.push((Box::new(filter), Box::new(handler)));
|
.push(FilterAndHandler::new(filter, handler));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,29 +259,24 @@ where
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle<T>(&self, update: T, handlers: &Handlers<'a, T, E>)
|
async fn handle<T>(
|
||||||
where
|
&self,
|
||||||
|
update: T,
|
||||||
|
handlers: &FiltersAndHandlers<'a, T, E>,
|
||||||
|
) where
|
||||||
T: std::fmt::Debug,
|
T: std::fmt::Debug,
|
||||||
{
|
{
|
||||||
let handler = handlers.iter().find_map(|e| {
|
for x in handlers {
|
||||||
let (filter, handler) = e;
|
if x.filter.test(&update) {
|
||||||
if filter.test(&update) {
|
if let Err(err) = x.handler.handle(update).await {
|
||||||
Some(handler)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
match handler {
|
|
||||||
Some(handler) => {
|
|
||||||
if let Err(err) = handler.handle(update).await {
|
|
||||||
self.error_policy.handle_error(err).await
|
self.error_policy.handle_error(err).await
|
||||||
}
|
}
|
||||||
}
|
|
||||||
None => {
|
return;
|
||||||
log::warn!("unhandled update {:?}", update);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log::warn!("unhandled update {:?}", update);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,8 +303,7 @@ mod tests {
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
dispatching::{
|
dispatching::{
|
||||||
dispatchers::filter::FilterDispatcher,
|
dispatchers::filter::FilterDispatcher, updater::StreamUpdater,
|
||||||
updater::StreamUpdater,
|
|
||||||
},
|
},
|
||||||
types::{
|
types::{
|
||||||
Chat, ChatKind, ForwardKind, MediaKind, Message, MessageKind,
|
Chat, ChatKind, ForwardKind, MediaKind, Message, MessageKind,
|
||||||
|
@ -301,7 +316,7 @@ mod tests {
|
||||||
let counter = &AtomicI32::new(0);
|
let counter = &AtomicI32::new(0);
|
||||||
let counter2 = &AtomicI32::new(0);
|
let counter2 = &AtomicI32::new(0);
|
||||||
|
|
||||||
let mut dp = FilterDispatcher::<Infallible, _>::new(|_| async { () } )
|
let mut dp = FilterDispatcher::<Infallible, _>::new(|_| async { () })
|
||||||
.message_handler(true, |_mes: Message| {
|
.message_handler(true, |_mes: Message| {
|
||||||
async move {
|
async move {
|
||||||
counter.fetch_add(1, Ordering::SeqCst);
|
counter.fetch_add(1, Ordering::SeqCst);
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
use std::{
|
use std::{borrow::Cow, path::PathBuf};
|
||||||
path::PathBuf,
|
|
||||||
borrow::Cow,
|
|
||||||
};
|
|
||||||
|
|
||||||
use reqwest::multipart::Form;
|
use reqwest::multipart::Form;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
requests::utils::file_to_part,
|
requests::utils::file_to_part,
|
||||||
types::{ChatId, InputMedia, ParseMode, InputFile},
|
types::{ChatId, InputFile, InputMedia, ParseMode},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This is a convenient struct that builds `reqwest::multipart::Form`
|
/// This is a convenient struct that builds `reqwest::multipart::Form`
|
||||||
|
@ -40,7 +37,7 @@ impl FormBuilder {
|
||||||
// used in SendMediaGroup
|
// used in SendMediaGroup
|
||||||
pub fn add_file<'a, N>(self, name: N, path_to_file: PathBuf) -> Self
|
pub fn add_file<'a, N>(self, name: N, path_to_file: PathBuf) -> Self
|
||||||
where
|
where
|
||||||
N: Into<Cow<'a, str>>
|
N: Into<Cow<'a, str>>,
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
form: self
|
form: self
|
||||||
|
|
Loading…
Add table
Reference in a new issue