Merge pull request #79 from telebofr/handles_type

Simplify 'type Handlers = ...' (dispatchers/filter/mod.rs)
This commit is contained in:
Temirkhan Myrzamadi 2019-11-04 01:19:30 +06:00 committed by GitHub
commit 1df08f02c7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 75 additions and 66 deletions

View file

@ -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 })
}

View file

@ -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,29 +259,24 @@ 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
}
}
None => {
log::warn!("unhandled update {:?}", update);
return;
}
}
log::warn!("unhandled update {:?}", update);
}
}
@ -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);

View file

@ -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