mirror of
https://github.com/teloxide/teloxide.git
synced 2025-01-09 11:43:57 +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::{
|
||||
pin::Pin,
|
||||
future::Future,
|
||||
convert::Infallible,
|
||||
};
|
||||
use std::{convert::Infallible, future::Future, pin::Pin};
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
||||
|
@ -21,8 +17,7 @@ pub trait ErrorPolicy<E> {
|
|||
/// # #[tokio::main]
|
||||
/// # async fn main() {
|
||||
/// use telebofr::dispatching::dispatchers::filter::error_policy::{
|
||||
/// ErrorPolicy,
|
||||
/// Ignore,
|
||||
/// ErrorPolicy, Ignore,
|
||||
/// };
|
||||
///
|
||||
/// Ignore.handle_error(()).await;
|
||||
|
@ -39,11 +34,13 @@ where
|
|||
{
|
||||
async fn handle_error(&self, _: E)
|
||||
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
|
||||
/// ```
|
||||
|
@ -68,8 +65,7 @@ where
|
|||
///
|
||||
/// ```compile_fail
|
||||
/// use telebofr::dispatching::dispatchers::filter::error_policy::{
|
||||
/// ErrorPolicy,
|
||||
/// IgnoreSafe,
|
||||
/// ErrorPolicy, IgnoreSafe,
|
||||
/// };
|
||||
///
|
||||
/// IgnoreSafe.handle_error(0);
|
||||
|
@ -90,7 +86,7 @@ pub struct IgnoreSafe;
|
|||
impl ErrorPolicy<!> for IgnoreSafe {
|
||||
async fn handle_error(&self, never: !)
|
||||
where
|
||||
!: 'async_trait
|
||||
!: 'async_trait,
|
||||
{
|
||||
never
|
||||
}
|
||||
|
@ -100,7 +96,7 @@ impl ErrorPolicy<!> for IgnoreSafe {
|
|||
impl ErrorPolicy<Infallible> for IgnoreSafe {
|
||||
async fn handle_error(&self, inf: Infallible)
|
||||
where
|
||||
Infallible: 'async_trait
|
||||
Infallible: 'async_trait,
|
||||
{
|
||||
match inf {}
|
||||
}
|
||||
|
@ -114,9 +110,7 @@ impl ErrorPolicy<Infallible> for IgnoreSafe {
|
|||
/// # async fn main() {
|
||||
/// use telebofr::dispatching::dispatchers::filter::error_policy::ErrorPolicy;
|
||||
///
|
||||
/// let closure = |e: i32| async move {
|
||||
/// eprintln!("Error code{}", e)
|
||||
/// };
|
||||
/// let closure = |e: i32| async move { eprintln!("Error code{}", e) };
|
||||
///
|
||||
/// closure.handle_error(404).await;
|
||||
/// # }
|
||||
|
@ -127,11 +121,14 @@ where
|
|||
Fut: Future<Output = ()> + 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
|
||||
's: 'async_trait,
|
||||
Self: 'async_trait,
|
||||
E: 'async_trait
|
||||
E: 'async_trait,
|
||||
{
|
||||
Box::pin(async move { self(error).await })
|
||||
}
|
||||
|
|
|
@ -12,8 +12,25 @@ use crate::{
|
|||
|
||||
pub mod error_policy;
|
||||
|
||||
type Handlers<'a, T, E> =
|
||||
Vec<(Box<dyn Filter<T> + 'a>, Box<dyn Handler<'a, T, E> + 'a>)>;
|
||||
struct FilterAndHandler<'a, T, E> {
|
||||
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.
|
||||
///
|
||||
|
@ -36,12 +53,14 @@ type Handlers<'a, T, E> =
|
|||
/// use std::convert::Infallible;
|
||||
///
|
||||
/// use telebofr::{
|
||||
/// Bot,
|
||||
/// types::Message,
|
||||
/// dispatching::{
|
||||
/// dispatchers::filter::{error_policy::ErrorPolicy, FilterDispatcher},
|
||||
/// dispatchers::filter::{
|
||||
/// error_policy::ErrorPolicy, FilterDispatcher,
|
||||
/// },
|
||||
/// updater::polling,
|
||||
/// },
|
||||
/// types::Message,
|
||||
/// Bot,
|
||||
/// };
|
||||
///
|
||||
/// async fn handle_edited_message(mes: Message) {
|
||||
|
@ -67,16 +86,18 @@ type Handlers<'a, T, E> =
|
|||
/// ```
|
||||
///
|
||||
/// [`std::fmt::Debug`]: std::fmt::Debug
|
||||
/// [Custom error policy]: crate::dispatching::filter::error_policy::ErrorPolicy::Custom
|
||||
/// [updater]: crate::dispatching::updater
|
||||
/// [Custom error policy]:
|
||||
/// crate::dispatching::filter::error_policy::ErrorPolicy::Custom [updater]:
|
||||
/// crate::dispatching::updater
|
||||
pub struct FilterDispatcher<'a, E, Ep> {
|
||||
message_handlers: Handlers<'a, Message, E>,
|
||||
edited_message_handlers: Handlers<'a, Message, E>,
|
||||
channel_post_handlers: Handlers<'a, Message, E>,
|
||||
edited_channel_post_handlers: Handlers<'a, Message, E>,
|
||||
inline_query_handlers: Handlers<'a, (), E>,
|
||||
chosen_inline_result_handlers: Handlers<'a, ChosenInlineResult, E>,
|
||||
callback_query_handlers: Handlers<'a, CallbackQuery, E>,
|
||||
message_handlers: FiltersAndHandlers<'a, Message, E>,
|
||||
edited_message_handlers: FiltersAndHandlers<'a, Message, E>,
|
||||
channel_post_handlers: FiltersAndHandlers<'a, Message, E>,
|
||||
edited_channel_post_handlers: FiltersAndHandlers<'a, Message, E>,
|
||||
inline_query_handlers: FiltersAndHandlers<'a, (), E>,
|
||||
chosen_inline_result_handlers:
|
||||
FiltersAndHandlers<'a, ChosenInlineResult, E>,
|
||||
callback_query_handlers: FiltersAndHandlers<'a, CallbackQuery, E>,
|
||||
error_policy: Ep,
|
||||
}
|
||||
|
||||
|
@ -104,7 +125,7 @@ where
|
|||
H: Handler<'a, Message, E> + 'a,
|
||||
{
|
||||
self.message_handlers
|
||||
.push((Box::new(filter), Box::new(handler)));
|
||||
.push(FilterAndHandler::new(filter, handler));
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -114,7 +135,7 @@ where
|
|||
H: Handler<'a, Message, E> + 'a,
|
||||
{
|
||||
self.edited_message_handlers
|
||||
.push((Box::new(filter), Box::new(handler)));
|
||||
.push(FilterAndHandler::new(filter, handler));
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -124,7 +145,7 @@ where
|
|||
H: Handler<'a, Message, E> + 'a,
|
||||
{
|
||||
self.channel_post_handlers
|
||||
.push((Box::new(filter), Box::new(handler)));
|
||||
.push(FilterAndHandler::new(filter, handler));
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -138,7 +159,7 @@ where
|
|||
H: Handler<'a, Message, E> + 'a,
|
||||
{
|
||||
self.edited_channel_post_handlers
|
||||
.push((Box::new(filter), Box::new(handler)));
|
||||
.push(FilterAndHandler::new(filter, handler));
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -148,7 +169,7 @@ where
|
|||
H: Handler<'a, (), E> + 'a,
|
||||
{
|
||||
self.inline_query_handlers
|
||||
.push((Box::new(filter), Box::new(handler)));
|
||||
.push(FilterAndHandler::new(filter, handler));
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -162,7 +183,7 @@ where
|
|||
H: Handler<'a, ChosenInlineResult, E> + 'a,
|
||||
{
|
||||
self.chosen_inline_result_handlers
|
||||
.push((Box::new(filter), Box::new(handler)));
|
||||
.push(FilterAndHandler::new(filter, handler));
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -172,7 +193,7 @@ where
|
|||
H: Handler<'a, CallbackQuery, E> + 'a,
|
||||
{
|
||||
self.callback_query_handlers
|
||||
.push((Box::new(filter), Box::new(handler)));
|
||||
.push(FilterAndHandler::new(filter, handler));
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -238,30 +259,25 @@ where
|
|||
.await;
|
||||
}
|
||||
|
||||
async fn handle<T>(&self, update: T, handlers: &Handlers<'a, T, E>)
|
||||
where
|
||||
async fn handle<T>(
|
||||
&self,
|
||||
update: T,
|
||||
handlers: &FiltersAndHandlers<'a, T, E>,
|
||||
) where
|
||||
T: std::fmt::Debug,
|
||||
{
|
||||
let handler = handlers.iter().find_map(|e| {
|
||||
let (filter, handler) = e;
|
||||
if filter.test(&update) {
|
||||
Some(handler)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
match handler {
|
||||
Some(handler) => {
|
||||
if let Err(err) = handler.handle(update).await {
|
||||
for x in handlers {
|
||||
if x.filter.test(&update) {
|
||||
if let Err(err) = x.handler.handle(update).await {
|
||||
self.error_policy.handle_error(err).await
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
None => {
|
||||
}
|
||||
|
||||
log::warn!("unhandled update {:?}", update);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait(? Send)]
|
||||
|
@ -287,8 +303,7 @@ mod tests {
|
|||
|
||||
use crate::{
|
||||
dispatching::{
|
||||
dispatchers::filter::FilterDispatcher,
|
||||
updater::StreamUpdater,
|
||||
dispatchers::filter::FilterDispatcher, updater::StreamUpdater,
|
||||
},
|
||||
types::{
|
||||
Chat, ChatKind, ForwardKind, MediaKind, Message, MessageKind,
|
||||
|
@ -301,7 +316,7 @@ mod tests {
|
|||
let counter = &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| {
|
||||
async move {
|
||||
counter.fetch_add(1, Ordering::SeqCst);
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
use std::{
|
||||
path::PathBuf,
|
||||
borrow::Cow,
|
||||
};
|
||||
use std::{borrow::Cow, path::PathBuf};
|
||||
|
||||
use reqwest::multipart::Form;
|
||||
|
||||
use crate::{
|
||||
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`
|
||||
|
@ -40,7 +37,7 @@ impl FormBuilder {
|
|||
// used in SendMediaGroup
|
||||
pub fn add_file<'a, N>(self, name: N, path_to_file: PathBuf) -> Self
|
||||
where
|
||||
N: Into<Cow<'a, str>>
|
||||
N: Into<Cow<'a, str>>,
|
||||
{
|
||||
Self {
|
||||
form: self
|
||||
|
|
Loading…
Reference in a new issue