Update README.md

This commit is contained in:
Temirkhan Myrzamadi 2020-07-26 04:14:42 +06:00
parent 0c688b2bd2
commit 3a53609937

View file

@ -189,7 +189,7 @@ A dialogue is described by an enumeration, where each variant is one of possible
[FSM]: https://en.wikipedia.org/wiki/Finite-state_machine [FSM]: https://en.wikipedia.org/wiki/Finite-state_machine
States and transition functions are placed into separated modules. For example, below is a bot, which asks you three questions: Below is a bot, which asks you three questions and then sends the answers back to you. Here's possible states for a dialogue:
([dialogue_bot/src/states.rs](https://github.com/teloxide/teloxide/blob/master/examples/dialogue_bot/src/states.rs)) ([dialogue_bot/src/states.rs](https://github.com/teloxide/teloxide/blob/master/examples/dialogue_bot/src/states.rs))
```rust ```rust
@ -199,36 +199,30 @@ States and transition functions are placed into separated modules. For example,
pub enum Dialogue { pub enum Dialogue {
#[default] #[default]
Start(StartState), Start(StartState),
ReceiveDaysOfWeek(ReceiveDaysOfWeekState), ReceiveFullName(ReceiveFullNameState),
Receive10x5Answer(Receive10x5AnswerState), ReceiveAge(ReceiveAgeState),
ReceiveGandalfAlternativeName(ReceiveGandalfAlternativeNameState), ReceiveLocation(ReceiveLocationState),
} }
#[derive(Default)] #[derive(Default)]
pub struct StartState; pub struct StartState;
pub struct ReceiveDaysOfWeekState { #[derive(Generic)]
rest: StartState, pub struct ReceiveFullNameState;
#[derive(Generic)]
pub struct ReceiveAgeState {
pub full_name: String,
} }
pub struct Receive10x5AnswerState { #[derive(Generic)]
rest: ReceiveDaysOfWeekState, pub struct ReceiveLocationState {
days_of_week: u8, pub full_name: String,
pub age: u8,
} }
pub struct ReceiveGandalfAlternativeNameState {
rest: Receive10x5AnswerState,
_10x5_answer: u8,
}
up!(
StartState -> ReceiveDaysOfWeekState,
ReceiveDaysOfWeekState + [days_of_week: u8] -> Receive10x5AnswerState,
Receive10x5AnswerState + [_10x5_answer: u8] -> ReceiveGandalfAlternativeNameState,
);
``` ```
The handy `up!` macro automatically generates functions that complete one state to another by appending a field. Here are the transition functions: ... and here are transition functions, which turn one state into another:
([dialogue_bot/src/transitions.rs](https://github.com/teloxide/teloxide/blob/master/examples/dialogue_bot/src/transitions.rs)) ([dialogue_bot/src/transitions.rs](https://github.com/teloxide/teloxide/blob/master/examples/dialogue_bot/src/transitions.rs))
```rust ```rust
@ -237,68 +231,65 @@ The handy `up!` macro automatically generates functions that complete one state
pub type Out = TransitionOut<Dialogue>; pub type Out = TransitionOut<Dialogue>;
#[teloxide(transition)] #[teloxide(transition)]
async fn start(state: StartState, cx: TransitionIn) -> Out { async fn start(_state: StartState, cx: TransitionIn) -> Out {
cx.answer_str("Let's start our test! How many days per week are there?") cx.answer_str("Let's start! What's your full name?").await?;
.await?; next(ReceiveFullNameState)
next(state.up())
} }
#[teloxide(transition)] #[teloxide(transition)]
async fn receive_days_of_week( async fn receive_full_name(
state: ReceiveDaysOfWeekState, state: ReceiveFullNameState,
cx: TransitionIn, cx: TransitionIn,
) -> Out { ) -> Out {
match cx.update.text().map(str::parse) { match cx.update.text_owned() {
Some(Ok(ans)) if ans == 7 => { Some(ans) => {
cx.answer_str("10*5 = ?").await?; cx.answer_str("How old are you?").await?;
next(state.up(ans)) next(ReceiveAgeState::up(state, ans))
} }
_ => { _ => {
cx.answer_str("Try again.").await?; cx.answer_str("Send me a text message.").await?;
next(state) next(state)
} }
} }
} }
#[teloxide(transition)] #[teloxide(transition)]
async fn receive_10x5_answer( async fn receive_age_state(state: ReceiveAgeState, cx: TransitionIn) -> Out {
state: Receive10x5AnswerState, match cx.update.text().map(str::parse::<u8>) {
cx: TransitionIn, Some(Ok(ans)) => {
) -> Out { cx.answer_str("What's your location?").await?;
match cx.update.text().map(str::parse) { next(ReceiveLocationState::up(state, ans))
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?; cx.answer_str("Send me a number.").await?;
next(state) next(state)
} }
} }
} }
#[teloxide(transition)] #[teloxide(transition)]
async fn receive_gandalf_alternative_name( async fn receive_location(
state: ReceiveGandalfAlternativeNameState, state: ReceiveLocationState,
cx: TransitionIn, cx: TransitionIn,
) -> Out { ) -> Out {
match cx.update.text() { match cx.update.text() {
Some(ans) if ans == "Mithrandir" => { Some(ans) => {
cx.answer_str( cx.answer_str(format!(
"Congratulations! You've successfully passed the test!", "Full name: {}\nAge: {}\nLocation: {}",
) state.full_name, state.age, ans
))
.await?; .await?;
exit() exit()
} }
_ => { _ => {
cx.answer_str("Try again.").await?; cx.answer_str("Send me a text message.").await?;
next(state) next(state)
} }
} }
} }
``` ```
And, finally, the `main` function looks like this: Finally, the `main` function looks like this:
([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