diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b6021e2..a8581de0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Implement `GetChatId` for `Update`. + - The `dialogue::enter()` function as a shortcut for `dptree::entry().enter_dialogue()`. ## 0.8.0 - 2022-04-18 diff --git a/examples/purchase.rs b/examples/purchase.rs index 28bb3d17..1d6560d1 100644 --- a/examples/purchase.rs +++ b/examples/purchase.rs @@ -13,7 +13,7 @@ // ``` use teloxide::{ - dispatching::dialogue::{GetChatId, InMemStorage}, + dispatching::dialogue::{self, GetChatId, InMemStorage}, prelude::*, types::{InlineKeyboardButton, InlineKeyboardMarkup}, utils::command::BotCommands, @@ -53,8 +53,7 @@ async fn main() { Dispatcher::builder( bot, - dptree::entry() - .enter_dialogue::, State>() + dialogue::enter::, State, _>() .branch( Update::filter_message() .chain(teloxide::handler![State::ReceiveFullName].endpoint(receive_full_name)), diff --git a/src/dispatching/dialogue/mod.rs b/src/dispatching/dialogue/mod.rs index 0a53d0d1..98f2887d 100644 --- a/src/dispatching/dialogue/mod.rs +++ b/src/dispatching/dialogue/mod.rs @@ -83,11 +83,14 @@ pub use crate::dispatching::dialogue::{RedisStorage, RedisStorageError}; #[cfg(feature = "sqlite-storage")] pub use crate::dispatching::dialogue::{SqliteStorage, SqliteStorageError}; +use dptree::{prelude::DependencyMap, Handler}; pub use get_chat_id::GetChatId; pub use storage::*; use teloxide_core::types::ChatId; -use std::{marker::PhantomData, sync::Arc}; +use std::{fmt::Debug, marker::PhantomData, sync::Arc}; + +use super::DpHandlerDescription; mod get_chat_id; mod storage; @@ -180,6 +183,37 @@ where } } +/// Enters a dialogue context. +/// +/// A call to this function is the same as `dptree::entry().enter_dialogue()`. +/// +/// See [`HandlerExt::enter_dialogue`]. +/// +/// [`HandlerExt::enter_dialogue`]: super::HandlerExt::enter_dialogue +pub fn enter() -> Handler<'static, DependencyMap, Output, DpHandlerDescription> +where + S: Storage + ?Sized + Send + Sync + 'static, + >::Error: Debug + Send, + D: Default + Send + Sync + 'static, + Upd: GetChatId + Clone + Send + Sync + 'static, + Output: Send + Sync + 'static, +{ + dptree::entry() + .chain(dptree::filter_map(|storage: Arc, upd: Upd| { + let chat_id = upd.chat_id()?; + Some(Dialogue::new(storage, chat_id)) + })) + .chain(dptree::filter_map_async(|dialogue: Dialogue| async move { + match dialogue.get_or_default().await { + Ok(dialogue) => Some(dialogue), + Err(err) => { + log::error!("dialogue.get_or_default() failed: {:?}", err); + None + } + } + })) +} + /// Perform a dialogue FSM transition. /// /// This macro expands to a [`dptree::Handler`] that filters your dialogue diff --git a/src/dispatching/handler_ext.rs b/src/dispatching/handler_ext.rs index a495e9d2..3e698140 100644 --- a/src/dispatching/handler_ext.rs +++ b/src/dispatching/handler_ext.rs @@ -1,8 +1,6 @@ -use std::sync::Arc; - use crate::{ dispatching::{ - dialogue::{Dialogue, GetChatId, Storage}, + dialogue::{GetChatId, Storage}, DpHandlerDescription, }, types::{Me, Message}, @@ -82,19 +80,7 @@ where D: Default + Send + Sync + 'static, Upd: GetChatId + Clone + Send + Sync + 'static, { - self.chain(dptree::filter_map(|storage: Arc, upd: Upd| { - let chat_id = upd.chat_id()?; - Some(Dialogue::new(storage, chat_id)) - })) - .chain(dptree::filter_map_async(|dialogue: Dialogue| async move { - match dialogue.get_or_default().await { - Ok(dialogue) => Some(dialogue), - Err(err) => { - log::error!("dialogue.get_or_default() failed: {:?}", err); - None - } - } - })) + self.chain(super::dialogue::enter::()) } #[allow(deprecated)]