Errors in handlers

This commit is contained in:
Waffle 2019-10-05 00:28:40 +03:00
parent f4a3c4f6bd
commit c51aa9728a
2 changed files with 62 additions and 32 deletions

View file

@ -1,17 +1,38 @@
use futures::FutureExt;
use std::future::Future; use std::future::Future;
use std::pin::Pin; use std::pin::Pin;
/// Asynchronous handler for event `I` (like `&self, I -> Future` fn) pub type HandlerResult<E> = Result<(), E>;
pub trait Handler<'a, I> {
fn handle(&self, value: I) -> Pin<Box<dyn Future<Output = ()> + 'a>>; /// Asynchronous handler for event `T` (like `&self, I -> Future` fn)
pub trait Handler<'a, T, E> {
fn handle(&self, value: T) -> Pin<Box<dyn Future<Output = HandlerResult<E>> + 'a>>;
} }
impl<'a, Fut, T, F> Handler<'a, T> for F pub trait IntoHandlerResult<E> {
where fn into_hr(self) -> HandlerResult<E>;
Fut: Future<Output = ()> + 'a, }
F: Fn(T) -> Fut,
{ impl<E> IntoHandlerResult<E> for () {
fn handle(&self, value: T) -> Pin<Box<dyn Future<Output = ()> + 'a>> { fn into_hr(self) -> HandlerResult<E> {
Box::pin((self)(value)) Ok(())
}
}
impl<E> IntoHandlerResult<E> for HandlerResult<E> {
fn into_hr(self) -> HandlerResult<E> {
self
}
}
impl<'a, F, Fut, R, T, E> Handler<'a, T, E> for F
where
F: Fn(T) -> Fut,
Fut: Future<Output = R> + 'a,
R: IntoHandlerResult<E> + 'a,
E: 'a,
{
fn handle(&self, value: T) -> Pin<Box<dyn Future<Output = HandlerResult<E>> + 'a>> {
Box::pin(self(value).map(IntoHandlerResult::into_hr))
} }
} }

View file

@ -16,19 +16,19 @@ use crate::{
use futures::StreamExt; use futures::StreamExt;
pub type Handlers<'a, T> = Vec<(Box<dyn Filter<T> + 'a>, Box<dyn Handler<'a, T> + 'a>)>; pub type Handlers<'a, T, E> = Vec<(Box<dyn Filter<T> + 'a>, Box<dyn Handler<'a, T, E> + 'a>)>;
pub struct Dispatcher<'a> { pub struct Dispatcher<'a, E> {
message_handlers: Handlers<'a, Message>, message_handlers: Handlers<'a, Message, E>,
edited_message_handlers: Handlers<'a, Message>, edited_message_handlers: Handlers<'a, Message, E>,
channel_post_handlers: Handlers<'a, Message>, channel_post_handlers: Handlers<'a, Message, E>,
edited_channel_post_handlers: Handlers<'a, Message>, edited_channel_post_handlers: Handlers<'a, Message, E>,
inline_query_handlers: Handlers<'a, ()>, inline_query_handlers: Handlers<'a, (), E>,
chosen_inline_result_handlers: Handlers<'a, ChosenInlineResult>, chosen_inline_result_handlers: Handlers<'a, ChosenInlineResult, E>,
callback_query_handlers: Handlers<'a, CallbackQuery>, callback_query_handlers: Handlers<'a, CallbackQuery, E>,
} }
impl<'a> Dispatcher<'a> { impl<'a, E> Dispatcher<'a, E> {
pub fn new() -> Self { pub fn new() -> Self {
Dispatcher { Dispatcher {
message_handlers: Vec::new(), message_handlers: Vec::new(),
@ -44,7 +44,7 @@ impl<'a> Dispatcher<'a> {
pub fn message_handler<F, H>(mut self, filter: F, handler: H) -> Self pub fn message_handler<F, H>(mut self, filter: F, handler: H) -> Self
where where
F: Filter<Message> + 'a, F: Filter<Message> + 'a,
H: Handler<'a, Message> + 'a, H: Handler<'a, Message, E> + 'a,
{ {
self.message_handlers.push((Box::new(filter), Box::new(handler))); self.message_handlers.push((Box::new(filter), Box::new(handler)));
self self
@ -53,7 +53,7 @@ impl<'a> Dispatcher<'a> {
pub fn edited_message_handler<F, H>(mut self, filter: F, handler: H) -> Self pub fn edited_message_handler<F, H>(mut self, filter: F, handler: H) -> Self
where where
F: Filter<Message> + 'a, F: Filter<Message> + 'a,
H: Handler<'a, Message> + 'a, H: Handler<'a, Message, E> + 'a,
{ {
self.edited_message_handlers.push((Box::new(filter), Box::new(handler))); self.edited_message_handlers.push((Box::new(filter), Box::new(handler)));
self self
@ -62,7 +62,7 @@ impl<'a> Dispatcher<'a> {
pub fn channel_post_handler<F, H>(mut self, filter: F, handler: H) -> Self pub fn channel_post_handler<F, H>(mut self, filter: F, handler: H) -> Self
where where
F: Filter<Message> + 'a, F: Filter<Message> + 'a,
H: Handler<'a, Message> + 'a, H: Handler<'a, Message, E> + 'a,
{ {
self.channel_post_handlers.push((Box::new(filter), Box::new(handler))); self.channel_post_handlers.push((Box::new(filter), Box::new(handler)));
self self
@ -71,7 +71,7 @@ impl<'a> Dispatcher<'a> {
pub fn edited_channel_post_handler<F, H>(mut self, filter: F, handler: H) -> Self pub fn edited_channel_post_handler<F, H>(mut self, filter: F, handler: H) -> Self
where where
F: Filter<Message> + 'a, F: Filter<Message> + 'a,
H: Handler<'a, Message> + 'a, H: Handler<'a, Message, E> + 'a,
{ {
self.edited_channel_post_handlers.push((Box::new(filter), Box::new(handler))); self.edited_channel_post_handlers.push((Box::new(filter), Box::new(handler)));
self self
@ -80,7 +80,7 @@ impl<'a> Dispatcher<'a> {
pub fn inline_query_handler<F, H>(mut self, filter: F, handler: H) -> Self pub fn inline_query_handler<F, H>(mut self, filter: F, handler: H) -> Self
where where
F: Filter<()> + 'a, F: Filter<()> + 'a,
H: Handler<'a, ()> + 'a, H: Handler<'a, (), E> + 'a,
{ {
self.inline_query_handlers.push((Box::new(filter), Box::new(handler))); self.inline_query_handlers.push((Box::new(filter), Box::new(handler)));
self self
@ -89,7 +89,7 @@ impl<'a> Dispatcher<'a> {
pub fn chosen_inline_result_handler<F, H>(mut self, filter: F, handler: H) -> Self pub fn chosen_inline_result_handler<F, H>(mut self, filter: F, handler: H) -> Self
where where
F: Filter<ChosenInlineResult> + 'a, F: Filter<ChosenInlineResult> + 'a,
H: Handler<'a, ChosenInlineResult> + 'a, H: Handler<'a, ChosenInlineResult, E> + 'a,
{ {
self.chosen_inline_result_handlers.push((Box::new(filter), Box::new(handler))); self.chosen_inline_result_handlers.push((Box::new(filter), Box::new(handler)));
self self
@ -98,16 +98,16 @@ impl<'a> Dispatcher<'a> {
pub fn callback_query_handler<F, H>(mut self, filter: F, handler: H) -> Self pub fn callback_query_handler<F, H>(mut self, filter: F, handler: H) -> Self
where where
F: Filter<CallbackQuery> + 'a, F: Filter<CallbackQuery> + 'a,
H: Handler<'a, CallbackQuery> + 'a, H: Handler<'a, CallbackQuery, E> + 'a,
{ {
self.callback_query_handlers.push((Box::new(filter), Box::new(handler))); self.callback_query_handlers.push((Box::new(filter), Box::new(handler)));
self self
} }
// TODO: Can someone simplify this? // TODO: Can someone simplify this?
pub async fn dispatch<U, E>(&mut self, updates: U) pub async fn dispatch<U, UE>(&mut self, updates: U)
where where
U: Updater<E> + 'a U: Updater<UE> + 'a
{ {
updates.for_each(|res| { updates.for_each(|res| {
async { async {
@ -133,7 +133,7 @@ impl<'a> Dispatcher<'a> {
}); });
match handler { match handler {
Some(handler) => handler.handle(value).await, Some(handler) => { handler.handle(value).await; /* todo */ },
None => log::warn!("Unhandled update: {:?}", value) None => log::warn!("Unhandled update: {:?}", value)
} }
}}; }};
@ -157,6 +157,8 @@ impl<'a> Dispatcher<'a> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::convert::Infallible;
#[tokio::test] #[tokio::test]
async fn test() { async fn test() {
use crate::{ use crate::{
@ -204,8 +206,15 @@ mod tests {
println!("{:#?}", mes) println!("{:#?}", mes)
} }
let mut dp = Dispatcher::new() async fn handler2(mes: Message) -> Result<(), Infallible>{
.message_handler(true, handler); println!("{:#?}", mes);
Ok(())
}
let mut dp = Dispatcher::<Infallible>::new()
.message_handler(true, handler)
.message_handler(true, handler2);
use futures::future::ready; use futures::future::ready;
use futures::stream; use futures::stream;