Update README.md

This commit is contained in:
Temirkhan Myrzamadi 2020-07-23 21:43:01 +06:00
parent f67d960d43
commit 324f0afaf4

133
README.md
View file

@ -188,44 +188,39 @@ States and transition functions are placed into separated modules. For example:
#[derive(Default)] #[derive(Default)]
pub struct StartState; pub struct StartState;
pub struct ReceiveFullNameState { pub struct ReceiveDaysOfWeekState {
rest: StartState, rest: StartState,
} }
pub struct ReceiveAgeState { pub struct Receive10x5AnswerState {
rest: ReceiveFullNameState, rest: ReceiveDaysOfWeekState,
full_name: String, days_of_week: u8,
} }
pub struct ReceiveFavouriteMusicState { pub struct ReceiveGandalfAlternativeNameState {
rest: ReceiveAgeState, rest: Receive10x5AnswerState,
age: u8, _10x5_answer: u8,
} }
#[derive(Display)]
#[display(
"Your full name: {rest.rest.full_name}, your age: {rest.age}, your \
favourite music: {favourite_music}"
)]
pub struct ExitState { pub struct ExitState {
rest: ReceiveFavouriteMusicState, rest: ReceiveGandalfAlternativeNameState,
favourite_music: FavouriteMusic, gandalf_alternative_name: String,
} }
up!( up!(
StartState -> ReceiveFullNameState, StartState -> ReceiveDaysOfWeekState,
ReceiveFullNameState + [full_name: String] -> ReceiveAgeState, ReceiveDaysOfWeekState + [days_of_week: u8] -> Receive10x5AnswerState,
ReceiveAgeState + [age: u8] -> ReceiveFavouriteMusicState, Receive10x5AnswerState + [_10x5_answer: u8] -> ReceiveGandalfAlternativeNameState,
ReceiveFavouriteMusicState + [favourite_music: FavouriteMusic] -> ExitState, ReceiveGandalfAlternativeNameState + [gandalf_alternative_name: String] -> ExitState,
); );
#[derive(SmartDefault, From)] #[derive(SmartDefault, From)]
pub enum Dialogue { pub enum Dialogue {
#[default] #[default]
Start(StartState), Start(StartState),
ReceiveFullName(ReceiveFullNameState), ReceiveDaysOfWeek(ReceiveDaysOfWeekState),
ReceiveAge(ReceiveAgeState), Receive10x5Answer(Receive10x5AnswerState),
ReceiveFavouriteMusic(ReceiveFavouriteMusicState), ReceiveGandalfAlternativeName(ReceiveGandalfAlternativeNameState),
} }
``` ```
@ -239,51 +234,51 @@ pub type Cx = UpdateWithCx<Message>;
pub type Out = TransitionOut<Dialogue>; pub type Out = TransitionOut<Dialogue>;
async fn start(cx: Cx, state: StartState) -> Out { async fn start(cx: Cx, state: StartState) -> Out {
cx.answer_str("Let's start! First, what's your full name?").await?; cx.answer_str("Let's start our test! How many days per week are there?")
.await?;
next(state.up()) next(state.up())
} }
async fn receive_full_name(cx: Cx, state: ReceiveFullNameState) -> Out { async fn receive_days_of_week(cx: Cx, state: ReceiveDaysOfWeekState) -> Out {
match cx.update.text_owned() {
Some(full_name) => {
cx.answer_str("What a wonderful name! Your age?").await?;
next(state.up(full_name))
}
_ => {
cx.answer_str("Please, enter a text message!").await?;
next(state)
}
}
}
async fn receive_age(cx: Cx, state: ReceiveAgeState) -> Out {
match cx.update.text().map(str::parse) { match cx.update.text().map(str::parse) {
Some(Ok(age)) => { Some(Ok(ans)) if ans == 7 => {
cx.answer("Good. Now choose your favourite music:") cx.answer_str("10*5 = ?").await?;
.reply_markup(FavouriteMusic::markup()) next(state.up(ans))
.send()
.await?;
next(state.up(age))
} }
_ => { _ => {
cx.answer_str("Please, enter a number!").await?; cx.answer_str("Try again.").await?;
next(state) next(state)
} }
} }
} }
async fn receive_favourite_music( async fn receive_10x5_answer(cx: Cx, state: Receive10x5AnswerState) -> Out {
match cx.update.text().map(str::parse) {
Some(Ok(ans)) if ans == 50 => {
cx.answer_str("What's an alternative name of Gandalf?").await?;
next(state.up(ans))
}
_ => {
cx.answer_str("Try again.").await?;
next(state)
}
}
}
async fn receive_gandalf_alternative_name(
cx: Cx, cx: Cx,
state: ReceiveFavouriteMusicState, state: ReceiveGandalfAlternativeNameState,
) -> Out { ) -> Out {
match cx.update.text().map(str::parse) { match cx.update.text() {
Some(Ok(favourite_music)) => { Some(ans) if ans == "Mithrandir" => {
cx.answer_str(format!("Fine. {}", state.up(favourite_music))) cx.answer_str(
.await?; "Congratulations! You've successfully passed the test!",
)
.await?;
exit() exit()
} }
_ => { _ => {
cx.answer_str("Please, enter from the keyboard!").await?; cx.answer_str("Try again.").await?;
next(state) next(state)
} }
} }
@ -292,41 +287,19 @@ async fn receive_favourite_music(
pub async fn dispatch(cx: Cx, dialogue: Dialogue) -> Out { pub async fn dispatch(cx: Cx, dialogue: Dialogue) -> Out {
match dialogue { match dialogue {
Dialogue::Start(state) => start(cx, state).await, Dialogue::Start(state) => start(cx, state).await,
Dialogue::ReceiveFullName(state) => receive_full_name(cx, state).await, Dialogue::ReceiveDaysOfWeek(state) => {
Dialogue::ReceiveAge(state) => receive_age(cx, state).await, receive_days_of_week(cx, state).await
Dialogue::ReceiveFavouriteMusic(state) => { }
receive_favourite_music(cx, state).await Dialogue::Receive10x5Answer(state) => {
receive_10x5_answer(cx, state).await
}
Dialogue::ReceiveGandalfAlternativeName(state) => {
receive_gandalf_alternative_name(cx, state).await
} }
} }
} }
``` ```
([dialogue_bot/src/favourite_music.rs](https://github.com/teloxide/teloxide/blob/master/examples/dialogue_bot/src/favourite_music.rs))
```rust
// Imports are omitted...
#[derive(Copy, Clone, Display, FromStr)]
pub enum FavouriteMusic {
Rock,
Metal,
Pop,
Other,
}
impl FavouriteMusic {
pub fn markup() -> ReplyKeyboardMarkup {
ReplyKeyboardMarkup::default().append_row(vec![
KeyboardButton::new("Rock"),
KeyboardButton::new("Metal"),
KeyboardButton::new("Pop"),
KeyboardButton::new("Other"),
])
}
}
```
([dialogue_bot/src/main.rs](https://github.com/teloxide/teloxide/blob/master/examples/dialogue_bot/src/main.rs)) ([dialogue_bot/src/main.rs](https://github.com/teloxide/teloxide/blob/master/examples/dialogue_bot/src/main.rs))
```rust ```rust
// Imports are omitted... // Imports are omitted...