Decompose guess-a-number-bot

This commit is contained in:
Temirkhan Myrzamadi 2020-03-09 14:01:45 +06:00
parent c0e7767bb3
commit ec7db5ec7b
2 changed files with 95 additions and 77 deletions

View file

@ -181,7 +181,7 @@ Wanna see more? This is a bot, which starts a game on each incoming message. You
([Full](https://github.com/teloxide/teloxide/blob/master/examples/guess_a_number_bot/src/main.rs)) ([Full](https://github.com/teloxide/teloxide/blob/master/examples/guess_a_number_bot/src/main.rs))
```rust ```rust
// Setup is omitted... // Imports are omitted...
#[derive(SmartDefault)] #[derive(SmartDefault)]
enum Dialogue { enum Dialogue {
@ -190,56 +190,57 @@ enum Dialogue {
ReceiveAttempt(u8), ReceiveAttempt(u8),
} }
async fn handle_message( type Cx<State> = DialogueDispatcherHandlerCx<Message, State>;
cx: DialogueDispatcherHandlerCx<Message, Dialogue>, type Res = ResponseResult<DialogueStage<Dialogue>>;
) -> ResponseResult<DialogueStage<Dialogue>> {
match cx.dialogue { async fn start(cx: Cx<()>) -> Res {
Dialogue::Start => { cx.answer("Let's play a game! Guess a number from 1 to 10 (inclusively).")
cx.answer( .send()
"Let's play a game! Guess a number from 1 to 10 (inclusively).", .await?;
) next(Dialogue::ReceiveAttempt(thread_rng().gen_range(1, 11)))
.send() }
.await?;
next(Dialogue::ReceiveAttempt(thread_rng().gen_range(1, 11))) async fn receive_attempt(cx: Cx<u8>) -> Res {
match cx.update.text() {
None => {
cx.answer("Oh, please, send me a text message!").send().await?;
next(Dialogue::ReceiveAttempt(cx.dialogue))
} }
Dialogue::ReceiveAttempt(secret) => match cx.update.text() { Some(text) => match text.parse::<u8>() {
None => { Ok(attempt) => match attempt {
cx.answer("Oh, please, send me a text message!").send().await?; x if !(1..=10).contains(&x) => {
next(cx.dialogue)
}
Some(text) => match text.parse::<u8>() {
Ok(attempt) => match attempt {
x if !(1..=10).contains(&x) => {
cx.answer(
"Oh, please, send me a number in the range [1; \
10]!",
)
.send()
.await?;
next(cx.dialogue)
}
x if x == secret => {
cx.answer("Congratulations! You won!").send().await?;
exit()
}
_ => {
cx.answer("No.").send().await?;
next(cx.dialogue)
}
},
Err(_) => {
cx.answer( cx.answer(
"Oh, please, send me a number in the range [1; 10]!", "Oh, please, send me a number in the range [1; 10]!",
) )
.send() .send()
.await?; .await?;
next(cx.dialogue) next(Dialogue::ReceiveAttempt(cx.dialogue))
}
x if x == cx.dialogue => {
cx.answer("Congratulations! You won!").send().await?;
exit()
}
_ => {
cx.answer("No.").send().await?;
next(Dialogue::ReceiveAttempt(cx.dialogue))
} }
}, },
Err(_) => {
cx.answer("Oh, please, send me a number in the range [1; 10]!")
.send()
.await?;
next(Dialogue::ReceiveAttempt(cx.dialogue))
}
}, },
} }
} }
async fn handle_message(
cx: DialogueDispatcherHandlerCx<Message, Dialogue>,
) -> Res {
// Match is Omitted...
}
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
// Setup is omitted... // Setup is omitted...

View file

@ -38,56 +38,73 @@ enum Dialogue {
// [Control a dialogue] // [Control a dialogue]
// ============================================================================ // ============================================================================
async fn handle_message( type Cx<State> = DialogueDispatcherHandlerCx<Message, State>;
cx: DialogueDispatcherHandlerCx<Message, Dialogue>, type Res = ResponseResult<DialogueStage<Dialogue>>;
) -> ResponseResult<DialogueStage<Dialogue>> {
match cx.dialogue { async fn start(cx: Cx<()>) -> Res {
Dialogue::Start => { cx.answer("Let's play a game! Guess a number from 1 to 10 (inclusively).")
cx.answer( .send()
"Let's play a game! Guess a number from 1 to 10 (inclusively).", .await?;
) next(Dialogue::ReceiveAttempt(thread_rng().gen_range(1, 11)))
.send() }
.await?;
next(Dialogue::ReceiveAttempt(thread_rng().gen_range(1, 11))) async fn receive_attempt(cx: Cx<u8>) -> Res {
match cx.update.text() {
None => {
cx.answer("Oh, please, send me a text message!").send().await?;
next(Dialogue::ReceiveAttempt(cx.dialogue))
} }
Dialogue::ReceiveAttempt(secret) => match cx.update.text() { Some(text) => match text.parse::<u8>() {
None => { Ok(attempt) => match attempt {
cx.answer("Oh, please, send me a text message!").send().await?; x if !(1..=10).contains(&x) => {
next(cx.dialogue)
}
Some(text) => match text.parse::<u8>() {
Ok(attempt) => match attempt {
x if !(1..=10).contains(&x) => {
cx.answer(
"Oh, please, send me a number in the range [1; \
10]!",
)
.send()
.await?;
next(cx.dialogue)
}
x if x == secret => {
cx.answer("Congratulations! You won!").send().await?;
exit()
}
_ => {
cx.answer("No.").send().await?;
next(cx.dialogue)
}
},
Err(_) => {
cx.answer( cx.answer(
"Oh, please, send me a number in the range [1; 10]!", "Oh, please, send me a number in the range [1; 10]!",
) )
.send() .send()
.await?; .await?;
next(cx.dialogue) next(Dialogue::ReceiveAttempt(cx.dialogue))
}
x if x == cx.dialogue => {
cx.answer("Congratulations! You won!").send().await?;
exit()
}
_ => {
cx.answer("No.").send().await?;
next(Dialogue::ReceiveAttempt(cx.dialogue))
} }
}, },
Err(_) => {
cx.answer("Oh, please, send me a number in the range [1; 10]!")
.send()
.await?;
next(Dialogue::ReceiveAttempt(cx.dialogue))
}
}, },
} }
} }
async fn handle_message(
cx: DialogueDispatcherHandlerCx<Message, Dialogue>,
) -> Res {
match cx {
DialogueDispatcherHandlerCx {
bot,
update,
dialogue: Dialogue::Start,
} => start(DialogueDispatcherHandlerCx::new(bot, update, ())).await,
DialogueDispatcherHandlerCx {
bot,
update,
dialogue: Dialogue::ReceiveAttempt(secret),
} => {
receive_attempt(DialogueDispatcherHandlerCx::new(
bot, update, secret,
))
.await
}
}
}
// ============================================================================ // ============================================================================
// [Run!] // [Run!]
// ============================================================================ // ============================================================================