diff --git a/src/dispatching/dialogue/dialogue_dispatcher.rs b/src/dispatching/dialogue/dialogue_dispatcher.rs index 18c0158d..00d0079f 100644 --- a/src/dispatching/dialogue/dialogue_dispatcher.rs +++ b/src/dispatching/dialogue/dialogue_dispatcher.rs @@ -47,25 +47,25 @@ where /// /// [`InMemStorage`]: crate::dispatching::dialogue::InMemStorage #[must_use] - pub fn new(handler: H) -> Arc { - Arc::new(Self { + pub fn new(handler: H) -> Self { + Self { storage: InMemStorage::new(), handler: Arc::new(handler), senders: Arc::new(Map::new()), - }) + } } /// Creates a dispatcher with the specified `handler` and `storage`. #[must_use] - pub fn with_storage(handler: H, storage: Arc) -> Arc + pub fn with_storage(handler: H, storage: Arc) -> Self where Stg: Storage + Send + Sync + 'static, { - Arc::new(Self { + Self { storage, handler: Arc::new(handler), senders: Arc::new(Map::new()), - }) + } } #[must_use] diff --git a/src/dispatching/dialogue/dialogue_dispatcher_handler.rs b/src/dispatching/dialogue/dialogue_dispatcher_handler.rs index 814de5eb..f52310a2 100644 --- a/src/dispatching/dialogue/dialogue_dispatcher_handler.rs +++ b/src/dispatching/dialogue/dialogue_dispatcher_handler.rs @@ -1,6 +1,5 @@ -use std::pin::Pin; - use crate::prelude::{DialogueDispatcherHandlerCtx, DialogueStage}; +use futures::future::BoxFuture; use std::{future::Future, sync::Arc}; /// An asynchronous handler of an update used in [`DialogueDispatcher`]. @@ -14,7 +13,7 @@ pub trait DialogueDispatcherHandler { fn handle( self: Arc, ctx: DialogueDispatcherHandlerCtx, - ) -> Pin> + Send + 'static>> + ) -> BoxFuture<'static, DialogueStage> where DialogueDispatcherHandlerCtx: Send + 'static; } @@ -27,7 +26,7 @@ where fn handle( self: Arc, ctx: DialogueDispatcherHandlerCtx, - ) -> Pin + Send + 'static>> + ) -> BoxFuture<'static, Fut::Output> where DialogueDispatcherHandlerCtx: Send + 'static, { diff --git a/src/dispatching/dispatcher.rs b/src/dispatching/dispatcher.rs index aee1a615..c3fdb4e3 100644 --- a/src/dispatching/dispatcher.rs +++ b/src/dispatching/dispatcher.rs @@ -211,7 +211,7 @@ impl Dispatcher { pub async fn dispatch(&self) { self.dispatch_with_listener( update_listeners::polling_default(Arc::clone(&self.bot)), - &LoggingErrorHandler::new("An error from the update listener"), + LoggingErrorHandler::new("An error from the update listener"), ) .await; } @@ -221,7 +221,7 @@ impl Dispatcher { pub async fn dispatch_with_listener<'a, UListener, ListenerE, Eh>( &'a self, update_listener: UListener, - update_listener_error_handler: &'a Eh, + update_listener_error_handler: Arc, ) where UListener: UpdateListener + 'a, Eh: ErrorHandler + 'a, @@ -230,105 +230,112 @@ impl Dispatcher { let update_listener = Box::pin(update_listener); update_listener - .for_each(move |update| async move { - log::trace!("Dispatcher received an update: {:?}", update); + .for_each(move |update| { + let update_listener_error_handler = + Arc::clone(&update_listener_error_handler); - let update = match update { - Ok(update) => update, - Err(error) => { - update_listener_error_handler.handle_error(error).await; - return; - } - }; + async move { + log::trace!("Dispatcher received an update: {:?}", update); - match update.kind { - UpdateKind::Message(message) => { - send!( - &self.bot, - &self.messages_queue, - message, - UpdateKind::Message - ); - } - UpdateKind::EditedMessage(message) => { - send!( - &self.bot, - &self.edited_messages_queue, - message, - UpdateKind::EditedMessage - ); - } - UpdateKind::ChannelPost(post) => { - send!( - &self.bot, - &self.channel_posts_queue, - post, - UpdateKind::ChannelPost - ); - } - UpdateKind::EditedChannelPost(post) => { - send!( - &self.bot, - &self.edited_channel_posts_queue, - post, - UpdateKind::EditedChannelPost - ); - } - UpdateKind::InlineQuery(query) => { - send!( - &self.bot, - &self.inline_queries_queue, - query, - UpdateKind::InlineQuery - ); - } - UpdateKind::ChosenInlineResult(result) => { - send!( - &self.bot, - &self.chosen_inline_results_queue, - result, - UpdateKind::ChosenInlineResult - ); - } - UpdateKind::CallbackQuery(query) => { - send!( - &self.bot, - &self.callback_queries_queue, - query, - UpdateKind::CallbackQuer - ); - } - UpdateKind::ShippingQuery(query) => { - send!( - &self.bot, - &self.shipping_queries_queue, - query, - UpdateKind::ShippingQuery - ); - } - UpdateKind::PreCheckoutQuery(query) => { - send!( - &self.bot, - &self.pre_checkout_queries_queue, - query, - UpdateKind::PreCheckoutQuery - ); - } - UpdateKind::Poll(poll) => { - send!( - &self.bot, - &self.polls_queue, - poll, - UpdateKind::Poll - ); - } - UpdateKind::PollAnswer(answer) => { - send!( - &self.bot, - &self.poll_answers_queue, - answer, - UpdateKind::PollAnswer - ); + let update = match update { + Ok(update) => update, + Err(error) => { + Arc::clone(&update_listener_error_handler) + .handle_error(error) + .await; + return; + } + }; + + match update.kind { + UpdateKind::Message(message) => { + send!( + &self.bot, + &self.messages_queue, + message, + UpdateKind::Message + ); + } + UpdateKind::EditedMessage(message) => { + send!( + &self.bot, + &self.edited_messages_queue, + message, + UpdateKind::EditedMessage + ); + } + UpdateKind::ChannelPost(post) => { + send!( + &self.bot, + &self.channel_posts_queue, + post, + UpdateKind::ChannelPost + ); + } + UpdateKind::EditedChannelPost(post) => { + send!( + &self.bot, + &self.edited_channel_posts_queue, + post, + UpdateKind::EditedChannelPost + ); + } + UpdateKind::InlineQuery(query) => { + send!( + &self.bot, + &self.inline_queries_queue, + query, + UpdateKind::InlineQuery + ); + } + UpdateKind::ChosenInlineResult(result) => { + send!( + &self.bot, + &self.chosen_inline_results_queue, + result, + UpdateKind::ChosenInlineResult + ); + } + UpdateKind::CallbackQuery(query) => { + send!( + &self.bot, + &self.callback_queries_queue, + query, + UpdateKind::CallbackQuer + ); + } + UpdateKind::ShippingQuery(query) => { + send!( + &self.bot, + &self.shipping_queries_queue, + query, + UpdateKind::ShippingQuery + ); + } + UpdateKind::PreCheckoutQuery(query) => { + send!( + &self.bot, + &self.pre_checkout_queries_queue, + query, + UpdateKind::PreCheckoutQuery + ); + } + UpdateKind::Poll(poll) => { + send!( + &self.bot, + &self.polls_queue, + poll, + UpdateKind::Poll + ); + } + UpdateKind::PollAnswer(answer) => { + send!( + &self.bot, + &self.poll_answers_queue, + answer, + UpdateKind::PollAnswer + ); + } } } }) diff --git a/src/dispatching/dispatcher_handler.rs b/src/dispatching/dispatcher_handler.rs index 58652414..2e89779e 100644 --- a/src/dispatching/dispatcher_handler.rs +++ b/src/dispatching/dispatcher_handler.rs @@ -1,6 +1,7 @@ -use std::{future::Future, pin::Pin}; +use std::future::Future; use crate::dispatching::{DispatcherHandlerCtx, DispatcherHandlerRx}; +use futures::future::BoxFuture; /// An asynchronous handler of a stream of updates used in [`Dispatcher`]. /// @@ -13,7 +14,7 @@ pub trait DispatcherHandler { fn handle( self, updates: DispatcherHandlerRx, - ) -> Pin + Send + 'static>> + ) -> BoxFuture<'static, ()> where DispatcherHandlerCtx: Send + 'static; } @@ -23,10 +24,7 @@ where F: FnOnce(DispatcherHandlerRx) -> Fut + Send + 'static, Fut: Future + Send + 'static, { - fn handle( - self, - updates: DispatcherHandlerRx, - ) -> Pin + Send + 'static>> + fn handle(self, updates: DispatcherHandlerRx) -> BoxFuture<'static, ()> where DispatcherHandlerCtx: Send + 'static, { diff --git a/src/dispatching/error_handlers.rs b/src/dispatching/error_handlers.rs index c9e1aa44..49e3eb78 100644 --- a/src/dispatching/error_handlers.rs +++ b/src/dispatching/error_handlers.rs @@ -1,4 +1,5 @@ -use std::{convert::Infallible, fmt::Debug, future::Future, pin::Pin}; +use futures::future::BoxFuture; +use std::{convert::Infallible, fmt::Debug, future::Future, sync::Arc}; /// An asynchronous handler of an error. /// @@ -6,26 +7,16 @@ use std::{convert::Infallible, fmt::Debug, future::Future, pin::Pin}; /// overview](crate::dispatching). pub trait ErrorHandler { #[must_use] - fn handle_error<'a>( - &'a self, - error: E, - ) -> Pin + 'a>> - where - E: 'a; + fn handle_error(self: Arc, error: E) -> BoxFuture<'static, ()>; } impl ErrorHandler for F where - F: Fn(E) -> Fut, - Fut: Future, + F: Fn(E) -> Fut + Send + Sync + 'static, + E: Send + 'static, + Fut: Future + Send, { - fn handle_error<'a>( - &'a self, - error: E, - ) -> Pin + 'a>> - where - E: 'a, - { + fn handle_error(self: Arc, error: E) -> BoxFuture<'static, ()> { Box::pin(async move { self(error).await }) } } @@ -38,21 +29,22 @@ where /// # async fn main_() { /// use teloxide::dispatching::{ErrorHandler, IgnoringErrorHandler}; /// -/// IgnoringErrorHandler.handle_error(()).await; -/// IgnoringErrorHandler.handle_error(404).await; -/// IgnoringErrorHandler.handle_error("error").await; +/// IgnoringErrorHandler::new().handle_error(()).await; +/// IgnoringErrorHandler::new().handle_error(404).await; +/// IgnoringErrorHandler::new().handle_error("error").await; /// # } /// ``` pub struct IgnoringErrorHandler; +impl IgnoringErrorHandler { + #[must_use] + pub fn new() -> Arc { + Arc::new(Self) + } +} + impl ErrorHandler for IgnoringErrorHandler { - fn handle_error<'a>( - &'a self, - _: E, - ) -> Pin + 'a>> - where - E: 'a, - { + fn handle_error(self: Arc, _: E) -> BoxFuture<'static, ()> { Box::pin(async {}) } } @@ -71,10 +63,10 @@ impl ErrorHandler for IgnoringErrorHandler { /// let result: Result = "str".try_into(); /// match result { /// Ok(string) => println!("{}", string), -/// Err(inf) => IgnoringErrorHandlerSafe.handle_error(inf).await, +/// Err(inf) => IgnoringErrorHandlerSafe::new().handle_error(inf).await, /// } /// -/// IgnoringErrorHandlerSafe.handle_error(return).await; // return type of `return` is `!` (aka never) +/// IgnoringErrorHandlerSafe::new().handle_error(return).await; // return type of `return` is `!` (aka never) /// # } /// ``` /// @@ -88,15 +80,16 @@ impl ErrorHandler for IgnoringErrorHandler { /// [`Infallible`]: std::convert::Infallible pub struct IgnoringErrorHandlerSafe; +impl IgnoringErrorHandlerSafe { + #[must_use] + pub fn new() -> Arc { + Arc::new(Self) + } +} + #[allow(unreachable_code)] impl ErrorHandler for IgnoringErrorHandlerSafe { - fn handle_error<'a>( - &'a self, - _: Infallible, - ) -> Pin + 'a>> - where - Infallible: 'a, - { + fn handle_error(self: Arc, _: Infallible) -> BoxFuture<'static, ()> { Box::pin(async {}) } } @@ -109,14 +102,13 @@ impl ErrorHandler for IgnoringErrorHandlerSafe { /// # async fn main_() { /// use teloxide::dispatching::{ErrorHandler, LoggingErrorHandler}; /// -/// LoggingErrorHandler::default().handle_error(()).await; +/// LoggingErrorHandler::empty().handle_error(()).await; /// LoggingErrorHandler::new("error").handle_error(404).await; /// LoggingErrorHandler::new("error") /// .handle_error("Invalid data type!") /// .await; /// # } /// ``` -#[derive(Default)] pub struct LoggingErrorHandler { text: String, } @@ -126,11 +118,17 @@ impl LoggingErrorHandler { /// /// The logs will be printed in this format: `{text}: {:?}`. #[must_use] - pub fn new(text: T) -> Self + pub fn new(text: T) -> Arc where T: Into, { - Self { text: text.into() } + Arc::new(Self { text: text.into() }) + } + + /// A shortcut for `LoggingErrorHandler::new("Error".to_owned())`. + #[must_use] + pub fn empty() -> Arc { + Self::new("Error".to_owned()) } } @@ -138,13 +136,7 @@ impl ErrorHandler for LoggingErrorHandler where E: Debug, { - fn handle_error<'a>( - &'a self, - error: E, - ) -> Pin + 'a>> - where - E: 'a, - { + fn handle_error(self: Arc, error: E) -> BoxFuture<'static, ()> { log::error!("{text}: {:?}", error, text = self.text); Box::pin(async {}) } diff --git a/src/prelude.rs b/src/prelude.rs index 8a17232b..5b7b9a7c 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -6,7 +6,8 @@ pub use crate::{ exit, next, DialogueDispatcher, DialogueDispatcherHandlerCtx, DialogueStage, GetChatId, }, - Dispatcher, DispatcherHandlerCtx, DispatcherHandlerRx, LoggingErrorHandler, ErrorHandler + Dispatcher, DispatcherHandlerCtx, DispatcherHandlerRx, ErrorHandler, + LoggingErrorHandler, }, requests::{Request, ResponseResult}, types::{Message, Update},