diff --git a/examples/redis_remember_bot/Cargo.toml b/examples/redis_remember_bot/Cargo.toml index 6a91b292..a5ad6b25 100644 --- a/examples/redis_remember_bot/Cargo.toml +++ b/examples/redis_remember_bot/Cargo.toml @@ -9,7 +9,10 @@ tokio = "0.2.9" # You can also choose "cbor-serializer" or built-in JSON serializer teloxide = { path = "../../", features = ["redis-storage", "bincode-serializer"] } +teloxide-macros = { git = "http://github.com/teloxide/teloxide-macros", branch = "master" } + serde = "1.0.104" +futures = "0.3.5" thiserror = "1.0.15" smart-default = "0.6.0" diff --git a/examples/redis_remember_bot/src/main.rs b/examples/redis_remember_bot/src/main.rs index 2b86b295..3d716972 100644 --- a/examples/redis_remember_bot/src/main.rs +++ b/examples/redis_remember_bot/src/main.rs @@ -7,7 +7,6 @@ mod states; mod transitions; use states::*; -use transitions::*; use teloxide::{ dispatching::dialogue::{serializer::Bincode, RedisStorage, Storage}, @@ -27,18 +26,6 @@ enum Error { type In = DialogueWithCx; -async fn handle_message(input: In) -> Out { - let (cx, dialogue) = input.unpack(); - - match cx.update.text_owned() { - Some(text) => dispatch(cx, dialogue, &text).await, - None => { - cx.answer_str("Please, send me a text message").await?; - next(StartState) - } - } -} - #[tokio::main] async fn main() { run().await; @@ -48,8 +35,11 @@ async fn run() { let bot = Bot::from_env(); Dispatcher::new(bot) .messages_handler(DialogueDispatcher::with_storage( - |cx| async move { - handle_message(cx) + |input: In| async move { + let (cx, dialogue) = input.unpack(); + + dialogue + .dispatch(cx) .await .expect("Something is wrong with the bot!") }, diff --git a/examples/redis_remember_bot/src/states.rs b/examples/redis_remember_bot/src/states.rs index 142e823a..927e7203 100644 --- a/examples/redis_remember_bot/src/states.rs +++ b/examples/redis_remember_bot/src/states.rs @@ -1,4 +1,7 @@ use teloxide::prelude::*; +use teloxide_macros::BotDialogue; + +use super::transitions::{have_number, start}; use serde::{Deserialize, Serialize}; @@ -15,9 +18,12 @@ up!( StartState + [number: i32] -> HaveNumberState, ); -#[derive(SmartDefault, From, Serialize, Deserialize)] +#[derive(BotDialogue, SmartDefault, From, Serialize, Deserialize)] pub enum Dialogue { #[default] + #[transition(start)] Start(StartState), + + #[transition(have_number)] HaveNumber(HaveNumberState), } diff --git a/examples/redis_remember_bot/src/transitions.rs b/examples/redis_remember_bot/src/transitions.rs index c294e9e4..f4bbb816 100644 --- a/examples/redis_remember_bot/src/transitions.rs +++ b/examples/redis_remember_bot/src/transitions.rs @@ -2,9 +2,24 @@ use teloxide::prelude::*; use super::states::*; +#[macro_export] +macro_rules! extract_text { + ($cx:ident) => { + match $cx.update.text_owned() { + Some(text) => text, + None => { + $cx.answer_str("Please, send me a text message").await?; + return next(StartState); + } + } + }; +} + pub type Out = TransitionOut; -async fn start(cx: TransitionIn, state: StartState, text: &str) -> Out { +pub async fn start(cx: TransitionIn, state: StartState) -> Out { + let text = extract_text!(cx); + if let Ok(number) = text.parse() { cx.answer_str(format!( "Remembered number {}. Now use /get or /reset", @@ -18,11 +33,8 @@ async fn start(cx: TransitionIn, state: StartState, text: &str) -> Out { } } -async fn have_number( - cx: TransitionIn, - state: HaveNumberState, - text: &str, -) -> Out { +pub async fn have_number(cx: TransitionIn, state: HaveNumberState) -> Out { + let text = extract_text!(cx); let num = state.number; if text.starts_with("/get") { @@ -36,10 +48,3 @@ async fn have_number( next(state) } } - -pub async fn dispatch(cx: TransitionIn, dialogue: Dialogue, text: &str) -> Out { - match dialogue { - Dialogue::Start(state) => start(cx, state, text).await, - Dialogue::HaveNumber(state) => have_number(cx, state, text).await, - } -}