mirror of
https://github.com/teloxide/teloxide.git
synced 2025-03-22 06:45:37 +01:00
Add dialogue::{next, exit}
This commit is contained in:
parent
809aaef9b1
commit
bde4d09e5d
8 changed files with 40 additions and 26 deletions
|
@ -11,6 +11,7 @@ pretty_env_logger = "0.3.1"
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
tokio = "0.2.9"
|
tokio = "0.2.9"
|
||||||
strum = "0.17.1"
|
strum = "0.17.1"
|
||||||
|
smart-default = "0.6.0"
|
||||||
strum_macros = "0.17.1"
|
strum_macros = "0.17.1"
|
||||||
teloxide = { path = "../../" }
|
teloxide = { path = "../../" }
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate strum_macros;
|
extern crate strum_macros;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate smart_default;
|
||||||
|
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
use teloxide::{
|
use teloxide::{
|
||||||
|
@ -57,19 +59,15 @@ impl Display for User {
|
||||||
// [States of a dialogue]
|
// [States of a dialogue]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
|
#[derive(SmartDefault)]
|
||||||
enum State {
|
enum State {
|
||||||
|
#[default]
|
||||||
Start,
|
Start,
|
||||||
FullName,
|
FullName,
|
||||||
Age,
|
Age,
|
||||||
FavouriteMusic,
|
FavouriteMusic,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for State {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::Start
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [Control a dialogue]
|
// [Control a dialogue]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
@ -90,14 +88,14 @@ async fn start(mut ctx: Ctx) -> Res {
|
||||||
ctx.reply("Let's start! First, what's your full name?")
|
ctx.reply("Let's start! First, what's your full name?")
|
||||||
.await?;
|
.await?;
|
||||||
ctx.dialogue.state = State::FullName;
|
ctx.dialogue.state = State::FullName;
|
||||||
Ok(DialogueStage::Next(ctx.dialogue))
|
next(ctx.dialogue)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn full_name(mut ctx: Ctx) -> Res {
|
async fn full_name(mut ctx: Ctx) -> Res {
|
||||||
ctx.reply("What a wonderful name! Your age?").await?;
|
ctx.reply("What a wonderful name! Your age?").await?;
|
||||||
ctx.dialogue.data.full_name = Some(ctx.update.text().unwrap().to_owned());
|
ctx.dialogue.data.full_name = Some(ctx.update.text().unwrap().to_owned());
|
||||||
ctx.dialogue.state = State::Age;
|
ctx.dialogue.state = State::Age;
|
||||||
Ok(DialogueStage::Next(ctx.dialogue))
|
next(ctx.dialogue)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn age(mut ctx: Ctx) -> Res {
|
async fn age(mut ctx: Ctx) -> Res {
|
||||||
|
@ -110,7 +108,7 @@ async fn age(mut ctx: Ctx) -> Res {
|
||||||
Err(_) => ctx.reply("Oh, please, enter a number!").await?,
|
Err(_) => ctx.reply("Oh, please, enter a number!").await?,
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(DialogueStage::Next(ctx.dialogue))
|
next(ctx.dialogue)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn favourite_music(mut ctx: Ctx) -> Res {
|
async fn favourite_music(mut ctx: Ctx) -> Res {
|
||||||
|
@ -118,11 +116,11 @@ async fn favourite_music(mut ctx: Ctx) -> Res {
|
||||||
Ok(ok) => {
|
Ok(ok) => {
|
||||||
ctx.dialogue.data.favourite_music = Some(ok);
|
ctx.dialogue.data.favourite_music = Some(ok);
|
||||||
ctx.reply(format!("Fine. {}", ctx.dialogue.data)).await?;
|
ctx.reply(format!("Fine. {}", ctx.dialogue.data)).await?;
|
||||||
Ok(DialogueStage::Exit)
|
exit()
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
ctx.reply("Oh, please, enter from the keyboard!").await?;
|
ctx.reply("Oh, please, enter from the keyboard!").await?;
|
||||||
Ok(DialogueStage::Next(ctx.dialogue))
|
next(ctx.dialogue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,7 +145,7 @@ async fn main() {
|
||||||
log::info!("Starting the simple_dialogue bot!");
|
log::info!("Starting the simple_dialogue bot!");
|
||||||
|
|
||||||
Dispatcher::new(Bot::new("YourAwesomeToken"))
|
Dispatcher::new(Bot::new("YourAwesomeToken"))
|
||||||
.message_handler(DialogueDispatcher::new(|ctx| async move {
|
.message_handler(&DialogueDispatcher::new(|ctx| async move {
|
||||||
handle_message(ctx)
|
handle_message(ctx)
|
||||||
.await
|
.await
|
||||||
.expect("Something wrong with the bot!")
|
.expect("Something wrong with the bot!")
|
||||||
|
|
20
src/dispatching/dialogue/dialogue_stage.rs
Normal file
20
src/dispatching/dialogue/dialogue_stage.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
use crate::dispatching::dialogue::Dialogue;
|
||||||
|
|
||||||
|
/// Continue or terminate a dialogue.
|
||||||
|
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq)]
|
||||||
|
pub enum DialogueStage<State, T> {
|
||||||
|
Next(Dialogue<State, T>),
|
||||||
|
Exit,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A shortcut for `Ok(DialogueStage::Next(dialogue))`.
|
||||||
|
pub fn next<E, State, T>(
|
||||||
|
dialogue: Dialogue<State, T>,
|
||||||
|
) -> Result<DialogueStage<State, T>, E> {
|
||||||
|
Ok(DialogueStage::Next(dialogue))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A shortcut for `Ok(DialogueStage::Exit)`.
|
||||||
|
pub fn exit<E, State, T>() -> Result<DialogueStage<State, T>, E> {
|
||||||
|
Ok(DialogueStage::Exit)
|
||||||
|
}
|
|
@ -1,8 +0,0 @@
|
||||||
use crate::dispatching::dialogue::Dialogue;
|
|
||||||
|
|
||||||
/// Continue or terminate a dialogue.
|
|
||||||
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq)]
|
|
||||||
pub enum DialogueStage<State, T> {
|
|
||||||
Next(Dialogue<State, T>),
|
|
||||||
Exit,
|
|
||||||
}
|
|
|
@ -37,13 +37,13 @@
|
||||||
mod dialogue;
|
mod dialogue;
|
||||||
mod dialogue_dispatcher;
|
mod dialogue_dispatcher;
|
||||||
mod dialogue_handler_ctx;
|
mod dialogue_handler_ctx;
|
||||||
mod dialogue_state;
|
mod dialogue_stage;
|
||||||
mod get_chat_id;
|
mod get_chat_id;
|
||||||
mod storage;
|
mod storage;
|
||||||
|
|
||||||
pub use dialogue::Dialogue;
|
pub use dialogue::Dialogue;
|
||||||
pub use dialogue_dispatcher::DialogueDispatcher;
|
pub use dialogue_dispatcher::DialogueDispatcher;
|
||||||
pub use dialogue_handler_ctx::DialogueHandlerCtx;
|
pub use dialogue_handler_ctx::DialogueHandlerCtx;
|
||||||
pub use dialogue_state::DialogueStage;
|
pub use dialogue_stage::{exit, next, DialogueStage};
|
||||||
pub use get_chat_id::GetChatId;
|
pub use get_chat_id::GetChatId;
|
||||||
pub use storage::{InMemStorage, Storage};
|
pub use storage::{InMemStorage, Storage};
|
||||||
|
|
|
@ -8,7 +8,7 @@ use crate::{
|
||||||
CallbackQuery, ChosenInlineResult, InlineQuery, Message, Poll,
|
CallbackQuery, ChosenInlineResult, InlineQuery, Message, Poll,
|
||||||
PollAnswer, PreCheckoutQuery, ShippingQuery, Update, UpdateKind,
|
PollAnswer, PreCheckoutQuery, ShippingQuery, Update, UpdateKind,
|
||||||
},
|
},
|
||||||
Bot,
|
Bot, RequestError,
|
||||||
};
|
};
|
||||||
use futures::{stream, StreamExt};
|
use futures::{stream, StreamExt};
|
||||||
use std::{fmt::Debug, future::Future, sync::Arc};
|
use std::{fmt::Debug, future::Future, sync::Arc};
|
||||||
|
@ -26,7 +26,9 @@ type Handlers<'a, Upd, HandlerE> = Vec<
|
||||||
///
|
///
|
||||||
/// See [the module-level documentation for the design
|
/// See [the module-level documentation for the design
|
||||||
/// overview](crate::dispatching).
|
/// overview](crate::dispatching).
|
||||||
pub struct Dispatcher<'a, HandlerE> {
|
// HandlerE=RequestError doesn't work now, because of very poor type inference.
|
||||||
|
// See https://github.com/rust-lang/rust/issues/27336 for more details.
|
||||||
|
pub struct Dispatcher<'a, HandlerE = RequestError> {
|
||||||
bot: Arc<Bot>,
|
bot: Arc<Bot>,
|
||||||
|
|
||||||
handlers_error_handler: Box<dyn ErrorHandler<HandlerE> + 'a>,
|
handlers_error_handler: Box<dyn ErrorHandler<HandlerE> + 'a>,
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
//!
|
//!
|
||||||
//! // Setup logging here...
|
//! // Setup logging here...
|
||||||
//!
|
//!
|
||||||
//! Dispatcher::new(Bot::new("MyAwesomeToken"))
|
//! Dispatcher::<RequestError>::new(Bot::new("MyAwesomeToken"))
|
||||||
//! .message_handler(&|ctx: DispatcherHandlerCtx<Message>| async move {
|
//! .message_handler(&|ctx: DispatcherHandlerCtx<Message>| async move {
|
||||||
//! ctx.answer("pong").send().await?;
|
//! ctx.answer("pong").send().await?;
|
||||||
//! Ok(())
|
//! Ok(())
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
dispatching::{
|
dispatching::{
|
||||||
dialogue::{
|
dialogue::{
|
||||||
DialogueDispatcher, DialogueHandlerCtx, DialogueStage, GetChatId,
|
exit, next, DialogueDispatcher, DialogueHandlerCtx, DialogueStage,
|
||||||
|
GetChatId,
|
||||||
},
|
},
|
||||||
Dispatcher, DispatcherHandlerCtx,
|
Dispatcher, DispatcherHandlerCtx,
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Reference in a new issue