mirror of
https://github.com/teloxide/teloxide.git
synced 2025-01-08 19:33:53 +01:00
Add auxiliary dialogues macros
This commit is contained in:
parent
963218bba0
commit
6ff1800f12
3 changed files with 55 additions and 52 deletions
|
@ -15,6 +15,7 @@
|
|||
// ```
|
||||
|
||||
#![allow(clippy::trivial_regex)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate frunk;
|
||||
|
@ -59,54 +60,37 @@ impl FavouriteMusic {
|
|||
|
||||
struct StartState;
|
||||
|
||||
impl StartState {
|
||||
fn up(self) -> ReceiveFullNameState {
|
||||
ReceiveFullNameState
|
||||
}
|
||||
struct ReceiveFullNameState {
|
||||
rest: StartState,
|
||||
}
|
||||
|
||||
struct ReceiveFullNameState;
|
||||
|
||||
impl ReceiveFullNameState {
|
||||
fn up(self, full_name: String) -> ReceiveAgeState {
|
||||
ReceiveAgeState { full_name }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct ReceiveAgeState {
|
||||
rest: ReceiveFullNameState,
|
||||
full_name: String,
|
||||
}
|
||||
|
||||
impl ReceiveAgeState {
|
||||
fn up(self, age: u8) -> ReceiveFavouriteMusicState {
|
||||
ReceiveFavouriteMusicState { full_name: self.full_name, age }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct ReceiveFavouriteMusicState {
|
||||
full_name: String,
|
||||
rest: ReceiveAgeState,
|
||||
age: u8,
|
||||
}
|
||||
|
||||
impl ReceiveFavouriteMusicState {
|
||||
fn up(self, favourite_music: FavouriteMusic) -> ExitState {
|
||||
ExitState { full_name: self.full_name, age: self.age, favourite_music }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Display)]
|
||||
#[display(
|
||||
"Your full name: {full_name}, your age: {age}, your favourite music: \
|
||||
{favourite_music}"
|
||||
"Your full name: {rest.rest.full_name}, your age: {rest.age}, your \
|
||||
favourite music: {favourite_music}"
|
||||
)]
|
||||
struct ExitState {
|
||||
full_name: String,
|
||||
age: u8,
|
||||
rest: ReceiveFavouriteMusicState,
|
||||
favourite_music: FavouriteMusic,
|
||||
}
|
||||
|
||||
up!(
|
||||
StartState -> ReceiveFullNameState,
|
||||
ReceiveFullNameState + [full_name: String] -> ReceiveAgeState,
|
||||
ReceiveAgeState + [age: u8] -> ReceiveFavouriteMusicState,
|
||||
ReceiveFavouriteMusicState + [favourite_music: FavouriteMusic] -> ExitState
|
||||
);
|
||||
|
||||
type Dialogue = Coprod!(
|
||||
StartState,
|
||||
ReceiveFullNameState,
|
||||
|
@ -114,7 +98,7 @@ type Dialogue = Coprod!(
|
|||
ReceiveFavouriteMusicState
|
||||
);
|
||||
|
||||
struct Wrapper(Dialogue);
|
||||
wrap_dialogue!(Wrapper, Dialogue);
|
||||
|
||||
impl Default for Wrapper {
|
||||
fn default() -> Self {
|
||||
|
@ -122,12 +106,6 @@ impl Default for Wrapper {
|
|||
}
|
||||
}
|
||||
|
||||
impl DialogueWrapper<Dialogue> for Wrapper {
|
||||
fn new(dialogue: Dialogue) -> Wrapper {
|
||||
Wrapper(dialogue)
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// [Control a dialogue]
|
||||
// ============================================================================
|
||||
|
@ -196,16 +174,6 @@ async fn favourite_music(cx: Cx<ReceiveFavouriteMusicState>) -> Res {
|
|||
}
|
||||
}
|
||||
|
||||
async fn handle_message(cx: Cx<Wrapper>) -> Res {
|
||||
let DialogueDispatcherHandlerCx { cx, dialogue } = cx;
|
||||
|
||||
// You need handle the error instead of panicking in real-world code, maybe
|
||||
// send diagnostics to a development chat.
|
||||
let Wrapper(dialogue) = dialogue.expect("Failed to get dialogue info from storage");
|
||||
|
||||
dispatch!([cx, dialogue] -> [start, full_name, age, favourite_music]);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// [Run!]
|
||||
// ============================================================================
|
||||
|
@ -223,7 +191,14 @@ async fn run() {
|
|||
|
||||
Dispatcher::new(bot)
|
||||
.messages_handler(DialogueDispatcher::new(|cx| async move {
|
||||
handle_message(cx).await.expect("Something wrong with the bot!")
|
||||
let DialogueDispatcherHandlerCx { cx, dialogue } = cx;
|
||||
|
||||
// You need handle the error instead of panicking in real-world code, maybe
|
||||
// send diagnostics to a development chat.
|
||||
let Wrapper(dialogue) = dialogue.expect("Failed to get dialogue info from storage");
|
||||
|
||||
dispatch!([cx, dialogue] -> [start, full_name, age, favourite_music])
|
||||
.expect("Something wrong with the bot!")
|
||||
}))
|
||||
.dispatch()
|
||||
.await;
|
||||
|
|
|
@ -61,7 +61,7 @@ macro_rules! dispatch {
|
|||
([$cx:ident, $dialogue:ident] -> [$transition:ident, $($transitions:ident),+]) => {
|
||||
match $dialogue {
|
||||
Coproduct::Inl(state) => {
|
||||
return $transition(teloxide::dispatching::dialogue::DialogueDispatcherHandlerCx::new($cx, state)).await;
|
||||
$transition(teloxide::dispatching::dialogue::DialogueDispatcherHandlerCx::new($cx, state)).await
|
||||
}
|
||||
Coproduct::Inr(another) => { dispatch!([$cx, another] -> [$($transitions),+]) }
|
||||
}
|
||||
|
@ -70,9 +70,37 @@ macro_rules! dispatch {
|
|||
([$cx:ident, $dialogue:ident] -> [$transition:ident]) => {
|
||||
match $dialogue {
|
||||
Coproduct::Inl(state) => {
|
||||
return $transition(teloxide::dispatching::dialogue::DialogueDispatcherHandlerCx::new($cx, state)).await;
|
||||
$transition(teloxide::dispatching::dialogue::DialogueDispatcherHandlerCx::new($cx, state)).await
|
||||
}
|
||||
Coproduct::Inr(_absurd) => unreachable!(),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! wrap_dialogue {
|
||||
($name:ident, $dialogue:ident) => {
|
||||
struct $name($dialogue);
|
||||
|
||||
impl teloxide::dispatching::dialogue::DialogueWrapper<$dialogue>
|
||||
for $name
|
||||
{
|
||||
fn new(d: $dialogue) -> Wrapper {
|
||||
$name(d)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! up {
|
||||
( $( $from:ident $(+ [$field_name:ident : $field_type:ty])? -> $to:ident ),+ ) => {
|
||||
$(
|
||||
impl $from {
|
||||
fn up(self, $( $field_name: $field_type )?) -> $to {
|
||||
$to { rest: self, $($field_name)? }
|
||||
}
|
||||
}
|
||||
)+
|
||||
};
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ pub use crate::{
|
|||
error_handlers::{LoggingErrorHandler, OnError},
|
||||
requests::{Request, ResponseResult},
|
||||
types::{Message, Update},
|
||||
Bot, RequestError,
|
||||
up, wrap_dialogue, Bot, RequestError,
|
||||
};
|
||||
|
||||
pub use tokio::sync::mpsc::UnboundedReceiver;
|
||||
|
|
Loading…
Reference in a new issue