diff --git a/README.md b/README.md index f041ac05..cc6f365b 100644 --- a/README.md +++ b/README.md @@ -190,23 +190,16 @@ Below is a bot that asks you three questions and then sends the answers back to ([Full](examples/dialogue.rs)) ```rust,ignore -use teloxide::{dispatching::dialogue::InMemStorage, macros::DialogueState, prelude::*}; +use teloxide::{dispatching::dialogue::InMemStorage, prelude::*}; type MyDialogue = Dialogue>; +type HandlerResult = Result<(), Box>; -#[derive(DialogueState, Clone)] -#[handler_out(anyhow::Result<()>)] +#[derive(Clone)] pub enum State { - #[handler(handle_start)] Start, - - #[handler(handle_receive_full_name)] ReceiveFullName, - - #[handler(handle_receive_age)] ReceiveAge { full_name: String }, - - #[handler(handle_receive_location)] ReceiveLocation { full_name: String, age: u8 }, } @@ -227,7 +220,13 @@ async fn main() { bot, Update::filter_message() .enter_dialogue::, State>() - .dispatch_by::(), + .branch(teloxide::handler![State::Start].endpoint(start)) + .branch(teloxide::handler![State::ReceiveFullName].endpoint(receive_full_name)) + .branch(teloxide::handler![State::ReceiveAge { full_name }].endpoint(receive_age)) + .branch( + teloxide::handler![State::ReceiveLocation { full_name, age }] + .endpoint(receive_location), + ), ) .dependencies(dptree::deps![InMemStorage::::new()]) .build() @@ -236,21 +235,17 @@ async fn main() { .await; } -async fn handle_start( - bot: AutoSend, - msg: Message, - dialogue: MyDialogue, -) -> anyhow::Result<()> { +async fn start(bot: AutoSend, msg: Message, dialogue: MyDialogue) -> HandlerResult { bot.send_message(msg.chat.id, "Let's start! What's your full name?").await?; dialogue.update(State::ReceiveFullName).await?; Ok(()) } -async fn handle_receive_full_name( +async fn receive_full_name( bot: AutoSend, msg: Message, dialogue: MyDialogue, -) -> anyhow::Result<()> { +) -> HandlerResult { match msg.text() { Some(text) => { bot.send_message(msg.chat.id, "How old are you?").await?; @@ -264,12 +259,12 @@ async fn handle_receive_full_name( Ok(()) } -async fn handle_receive_age( +async fn receive_age( bot: AutoSend, msg: Message, dialogue: MyDialogue, (full_name,): (String,), // Available from `State::ReceiveAge`. -) -> anyhow::Result<()> { +) -> HandlerResult { match msg.text().map(|text| text.parse::()) { Some(Ok(age)) => { bot.send_message(msg.chat.id, "What's your location?").await?; @@ -283,12 +278,12 @@ async fn handle_receive_age( Ok(()) } -async fn handle_receive_location( +async fn receive_location( bot: AutoSend, msg: Message, dialogue: MyDialogue, (full_name, age): (String, u8), // Available from `State::ReceiveLocation`. -) -> anyhow::Result<()> { +) -> HandlerResult { match msg.text() { Some(location) => { let message = format!("Full name: {}\nAge: {}\nLocation: {}", full_name, age, location); diff --git a/examples/db_remember.rs b/examples/db_remember.rs index 589e0578..21089ca1 100644 --- a/examples/db_remember.rs +++ b/examples/db_remember.rs @@ -6,9 +6,7 @@ use teloxide::{ serializer::{Bincode, Json}, ErasedStorage, RedisStorage, SqliteStorage, Storage, }, - macros::DialogueState, prelude::*, - types::Me, utils::command::BotCommand, }; @@ -16,13 +14,9 @@ type MyDialogue = Dialogue>; type MyStorage = std::sync::Arc>; type HandlerResult = Result<(), Box>; -#[derive(DialogueState, Clone, serde::Serialize, serde::Deserialize)] -#[handler_out(HandlerResult)] +#[derive(Clone, serde::Serialize, serde::Deserialize)] pub enum State { - #[handler(handle_start)] Start, - - #[handler(handle_got_number)] GotNumber(i32), } @@ -32,7 +26,7 @@ impl Default for State { } } -#[derive(BotCommand)] +#[derive(BotCommand, Clone)] #[command(rename = "lowercase", description = "These commands are supported:")] pub enum Command { #[command(description = "get your number.")] @@ -56,7 +50,12 @@ async fn main() { let handler = Update::filter_message() .enter_dialogue::, State>() - .dispatch_by::(); + .branch(teloxide::handler![State::Start].endpoint(start)) + .branch( + teloxide::handler![State::GotNumber(n)] + .branch(dptree::entry().filter_command::().endpoint(got_number)) + .branch(dptree::endpoint(invalid_command)), + ); Dispatcher::builder(bot, handler) .dependencies(dptree::deps![storage]) @@ -66,48 +65,44 @@ async fn main() { .await; } -async fn handle_start(bot: AutoSend, msg: Message, dialogue: MyDialogue) -> HandlerResult { - match msg.text().unwrap().parse() { - Ok(number) => { - dialogue.update(State::GotNumber(number)).await?; +async fn start(bot: AutoSend, msg: Message, dialogue: MyDialogue) -> HandlerResult { + match msg.text().map(|text| text.parse::()) { + Some(Ok(n)) => { + dialogue.update(State::GotNumber(n)).await?; bot.send_message( msg.chat.id, - format!("Remembered number {}. Now use /get or /reset", number), + format!("Remembered number {}. Now use /get or /reset.", n), ) .await?; } _ => { - bot.send_message(msg.chat.id, "Please, send me a number").await?; + bot.send_message(msg.chat.id, "Please, send me a number.").await?; } } Ok(()) } -async fn handle_got_number( +async fn got_number( bot: AutoSend, msg: Message, dialogue: MyDialogue, num: i32, - me: Me, + cmd: Command, ) -> HandlerResult { - let ans = msg.text().unwrap(); - let bot_name = me.user.username.unwrap(); - - match Command::parse(ans, bot_name) { - Ok(cmd) => match cmd { - Command::Get => { - bot.send_message(msg.chat.id, format!("Here is your number: {}", num)).await?; - } - Command::Reset => { - dialogue.reset().await?; - bot.send_message(msg.chat.id, "Number resetted").await?; - } - }, - Err(_) => { - bot.send_message(msg.chat.id, "Please, send /get or /reset").await?; + match cmd { + Command::Get => { + bot.send_message(msg.chat.id, format!("Here is your number: {}.", num)).await?; + } + Command::Reset => { + dialogue.reset().await?; + bot.send_message(msg.chat.id, "Number resetted.").await?; } } - + Ok(()) +} + +async fn invalid_command(bot: AutoSend, msg: Message) -> HandlerResult { + bot.send_message(msg.chat.id, "Please, send /get or /reset.").await?; Ok(()) } diff --git a/examples/dialogue.rs b/examples/dialogue.rs index 7c3438c9..d27370d4 100644 --- a/examples/dialogue.rs +++ b/examples/dialogue.rs @@ -13,24 +13,16 @@ // Age: 223 // Location: Middle-earth // ``` -use teloxide::{dispatching::dialogue::InMemStorage, macros::DialogueState, prelude::*}; +use teloxide::{dispatching::dialogue::InMemStorage, prelude::*}; type MyDialogue = Dialogue>; type HandlerResult = Result<(), Box>; -#[derive(DialogueState, Clone)] -#[handler_out(HandlerResult)] +#[derive(Clone)] pub enum State { - #[handler(handle_start)] Start, - - #[handler(handle_receive_full_name)] ReceiveFullName, - - #[handler(handle_receive_age)] ReceiveAge { full_name: String }, - - #[handler(handle_receive_location)] ReceiveLocation { full_name: String, age: u8 }, } @@ -51,7 +43,13 @@ async fn main() { bot, Update::filter_message() .enter_dialogue::, State>() - .dispatch_by::(), + .branch(teloxide::handler![State::Start].endpoint(start)) + .branch(teloxide::handler![State::ReceiveFullName].endpoint(receive_full_name)) + .branch(teloxide::handler![State::ReceiveAge { full_name }].endpoint(receive_age)) + .branch( + teloxide::handler![State::ReceiveLocation { full_name, age }] + .endpoint(receive_location), + ), ) .dependencies(dptree::deps![InMemStorage::::new()]) .build() @@ -60,13 +58,13 @@ async fn main() { .await; } -async fn handle_start(bot: AutoSend, msg: Message, dialogue: MyDialogue) -> HandlerResult { +async fn start(bot: AutoSend, msg: Message, dialogue: MyDialogue) -> HandlerResult { bot.send_message(msg.chat.id, "Let's start! What's your full name?").await?; dialogue.update(State::ReceiveFullName).await?; Ok(()) } -async fn handle_receive_full_name( +async fn receive_full_name( bot: AutoSend, msg: Message, dialogue: MyDialogue, @@ -84,7 +82,7 @@ async fn handle_receive_full_name( Ok(()) } -async fn handle_receive_age( +async fn receive_age( bot: AutoSend, msg: Message, dialogue: MyDialogue, @@ -103,7 +101,7 @@ async fn handle_receive_age( Ok(()) } -async fn handle_receive_location( +async fn receive_location( bot: AutoSend, msg: Message, dialogue: MyDialogue,