mirror of
https://github.com/teloxide/teloxide.git
synced 2025-03-24 23:57:38 +01:00
Fix the docs of dispatching::dialogue
This commit is contained in:
parent
a79bb7ba4f
commit
bdab7afe64
8 changed files with 110 additions and 32 deletions
|
@ -1,10 +1,4 @@
|
||||||
use crate::{
|
use crate::dispatching::dialogue::{TransitionIn, TransitionOut};
|
||||||
dispatching::{
|
|
||||||
dialogue::{TransitionIn, TransitionOut},
|
|
||||||
UpdateWithCx,
|
|
||||||
},
|
|
||||||
types::Message,
|
|
||||||
};
|
|
||||||
use futures::future::BoxFuture;
|
use futures::future::BoxFuture;
|
||||||
|
|
||||||
/// Represents a dialogue FSM.
|
/// Represents a dialogue FSM.
|
||||||
|
|
|
@ -15,11 +15,11 @@ use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
/// A dispatcher of dialogues.
|
/// A dispatcher of dialogues.
|
||||||
///
|
///
|
||||||
/// Note that `DialogueDispatcher` implements [`DispatcherHandler`], so you can
|
/// Note that it implements [`DispatcherHandler`], so you can just put an
|
||||||
/// just put an instance of this dispatcher into the [`Dispatcher`]'s methods.
|
/// instance of this dispatcher into the [`Dispatcher`]'s methods.
|
||||||
///
|
///
|
||||||
/// See [the module-level documentation for the design
|
/// See the [module-level documentation](crate::dispatching::dialogue) for the
|
||||||
/// overview](crate::dispatching::dialogue).
|
/// design overview.
|
||||||
///
|
///
|
||||||
/// [`Dispatcher`]: crate::dispatching::Dispatcher
|
/// [`Dispatcher`]: crate::dispatching::Dispatcher
|
||||||
/// [`DispatcherHandler`]: crate::dispatching::DispatcherHandler
|
/// [`DispatcherHandler`]: crate::dispatching::DispatcherHandler
|
||||||
|
|
|
@ -1,20 +1,19 @@
|
||||||
//! Dealing with dialogues.
|
//! Dealing with dialogues.
|
||||||
//!
|
//!
|
||||||
//! There are four main components:
|
//! There are three main components:
|
||||||
|
//!
|
||||||
|
//! 1. Your type `D` (typically an enumeration), implementing [`BotDialogue`].
|
||||||
|
//! It is essentially a [FSM]: its variants are possible dialogue states and
|
||||||
|
//! [`BotDialogue::dispatch`] is a transition function.
|
||||||
//!
|
//!
|
||||||
//! 1. Your type `D`, which designates a dialogue state at the current
|
|
||||||
//! moment.
|
|
||||||
//! 2. [`Storage<D>`], which encapsulates all the dialogues.
|
//! 2. [`Storage<D>`], which encapsulates all the dialogues.
|
||||||
//! 3. Your handler, which receives an update and turns your dialogue into the
|
//!
|
||||||
//! next state ([`DialogueDispatcherHandlerCx<YourUpdate, D>`] ->
|
//! 3. [`DialogueDispatcher`], which encapsulates your handler, [`Storage<D>`],
|
||||||
//! [`DialogueStage<D>`]).
|
|
||||||
//! 4. [`DialogueDispatcher`], which encapsulates your handler, [`Storage<D>`],
|
|
||||||
//! and implements [`DispatcherHandler`].
|
//! and implements [`DispatcherHandler`].
|
||||||
//!
|
//!
|
||||||
//! For example, you supply [`DialogueDispatcher`] into
|
//! You pass [`DialogueDispatcher`] into [`Dispatcher`]. Every time
|
||||||
//! [`Dispatcher::messages_handler`]. Every time [`Dispatcher`] sees an incoming
|
//! [`Dispatcher`] sees an incoming input, it is transferred into
|
||||||
//! [`UpdateKind::Message(message)`], `message` is transferred into
|
//! [`DialogueDispatcher`], and the following steps are executed:
|
||||||
//! [`DialogueDispatcher`]. After this, following steps are executed:
|
|
||||||
//!
|
//!
|
||||||
//! 1. If a storage doesn't contain a dialogue from this chat, supply
|
//! 1. If a storage doesn't contain a dialogue from this chat, supply
|
||||||
//! `D::default()` into you handler, otherwise, supply the saved dialogue
|
//! `D::default()` into you handler, otherwise, supply the saved dialogue
|
||||||
|
@ -23,21 +22,102 @@
|
||||||
//! from the storage, otherwise ([`DialogueStage::Next`]) force the storage to
|
//! from the storage, otherwise ([`DialogueStage::Next`]) force the storage to
|
||||||
//! update the dialogue.
|
//! update the dialogue.
|
||||||
//!
|
//!
|
||||||
//! Please, see [examples/dialogue_bot] as an example.
|
//! To avoid boilerplate, teloxide exports these convenient things: the [`up!`]
|
||||||
|
//! macro, the [`next`] and [`exit`] functions, and `#[derive(BotDialogue)]`.
|
||||||
|
//! Here's how your dialogues management code skeleton should look like:
|
||||||
|
//!
|
||||||
|
//! ```no_run
|
||||||
|
//! use std::convert::Infallible;
|
||||||
|
//!
|
||||||
|
//! use teloxide::prelude::*;
|
||||||
|
//! use teloxide_macros::BotDialogue;
|
||||||
|
//!
|
||||||
|
//! struct _1State;
|
||||||
|
//! struct _2State;
|
||||||
|
//! struct _3State;
|
||||||
|
//!
|
||||||
|
//! pub type Out = TransitionOut<D>;
|
||||||
|
//!
|
||||||
|
//! pub async fn _1_transition(cx: TransitionIn, state: _1State) {
|
||||||
|
//! todo!()
|
||||||
|
//! }
|
||||||
|
//! pub async fn _2_transition(cx: TransitionIn, state: _2State) {
|
||||||
|
//! todo!()
|
||||||
|
//! }
|
||||||
|
//! pub async fn _3_transition(cx: TransitionIn, state: _3State) {
|
||||||
|
//! todo!()
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! #[derive(BotDialogue)]
|
||||||
|
//! enum D {
|
||||||
|
//! #[transition(_1_transition)]
|
||||||
|
//! _1(_1State),
|
||||||
|
//! #[transition(_2_transition)]
|
||||||
|
//! _2(_2State),
|
||||||
|
//! #[transition(_3_transition)]
|
||||||
|
//! _3(_3State),
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! impl Default for D {
|
||||||
|
//! fn default() -> Self {
|
||||||
|
//! Self::_1(_1State)
|
||||||
|
//! }
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! #[tokio::main]
|
||||||
|
//! async fn main() {
|
||||||
|
//! run().await;
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! async fn run() {
|
||||||
|
//! teloxide::enable_logging!();
|
||||||
|
//! log::info!("Starting dialogue_bot!");
|
||||||
|
//!
|
||||||
|
//! let bot = Bot::from_env();
|
||||||
|
//!
|
||||||
|
//! Dispatcher::new(bot)
|
||||||
|
//! .messages_handler(DialogueDispatcher::new(
|
||||||
|
//! |input: DialogueWithCx<Message, D, Infallible>| async move {
|
||||||
|
//! // Unwrap without panic because of std::convert::Infallible.
|
||||||
|
//! input
|
||||||
|
//! .dialogue
|
||||||
|
//! .unwrap()
|
||||||
|
//! .dispatch(input.cx)
|
||||||
|
//! .await
|
||||||
|
//! .expect("Something wrong with the bot!")
|
||||||
|
//! },
|
||||||
|
//! ))
|
||||||
|
//! .dispatch()
|
||||||
|
//! .await;
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! See [examples/dialogue_bot] as a real example.
|
||||||
|
//!
|
||||||
|
//! [`BotDialogue`]: crate::dispatching::dialogue::BotDialogue
|
||||||
|
//! [`BotDialogue::dispatch`]:
|
||||||
|
//! crate::dispatching::dialogue::BotDialogue::dispatch
|
||||||
|
//! [FSM]: https://en.wikipedia.org/wiki/Finite-state_machine
|
||||||
//!
|
//!
|
||||||
//! [`Storage<D>`]: crate::dispatching::dialogue::Storage
|
//! [`Storage<D>`]: crate::dispatching::dialogue::Storage
|
||||||
|
//!
|
||||||
//! [`DialogueStage<D>`]: crate::dispatching::dialogue::DialogueStage
|
//! [`DialogueStage<D>`]: crate::dispatching::dialogue::DialogueStage
|
||||||
//! [`DialogueDispatcher`]: crate::dispatching::dialogue::DialogueDispatcher
|
//! [`DialogueDispatcher`]: crate::dispatching::dialogue::DialogueDispatcher
|
||||||
|
//!
|
||||||
//! [`DialogueStage::Exit`]:
|
//! [`DialogueStage::Exit`]:
|
||||||
//! crate::dispatching::dialogue::DialogueStage::Exit
|
//! crate::dispatching::dialogue::DialogueStage::Exit
|
||||||
//! [`DialogueStage::Next`]: crate::dispatching::dialogue::DialogueStage::Next
|
//! [`DialogueStage::Next`]: crate::dispatching::dialogue::DialogueStage::Next
|
||||||
|
//!
|
||||||
|
//! [`up!`]: crate::up
|
||||||
|
//! [`next`]: crate::dispatching::dialogue::next
|
||||||
|
//! [`exit`]: crate::dispatching::dialogue::exit
|
||||||
|
//!
|
||||||
//! [`DispatcherHandler`]: crate::dispatching::DispatcherHandler
|
//! [`DispatcherHandler`]: crate::dispatching::DispatcherHandler
|
||||||
//! [`Dispatcher`]: crate::dispatching::Dispatcher
|
//! [`Dispatcher`]: crate::dispatching::Dispatcher
|
||||||
//! [`Dispatcher::messages_handler`]:
|
//! [`Dispatcher::messages_handler`]:
|
||||||
//! crate::dispatching::Dispatcher::messages_handler
|
//! crate::dispatching::Dispatcher::messages_handler
|
||||||
//! [`UpdateKind::Message(message)`]: crate::types::UpdateKind::Message
|
//! [`UpdateKind::Message(message)`]: crate::types::UpdateKind::Message
|
||||||
//! [`DialogueWithCx<YourUpdate, D>`]:
|
//!
|
||||||
//! crate::dispatching::dialogue::DialogueWithCx
|
|
||||||
//! [examples/dialogue_bot]: https://github.com/teloxide/teloxide/tree/master/examples/dialogue_bot
|
//! [examples/dialogue_bot]: https://github.com/teloxide/teloxide/tree/master/examples/dialogue_bot
|
||||||
|
|
||||||
#![allow(clippy::type_complexity)]
|
#![allow(clippy::type_complexity)]
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/// Various serializers for memory storages.
|
//! Various serializers for memory storages.
|
||||||
|
|
||||||
use serde::{de::DeserializeOwned, ser::Serialize};
|
use serde::{de::DeserializeOwned, ser::Serialize};
|
||||||
|
|
||||||
/// A serializer for memory storages.
|
/// A serializer for memory storages.
|
||||||
|
|
|
@ -48,8 +48,8 @@ fn send<'a, Upd>(
|
||||||
|
|
||||||
/// One dispatcher to rule them all.
|
/// One dispatcher to rule them all.
|
||||||
///
|
///
|
||||||
/// See [the module-level documentation for the design
|
/// See the [module-level documentation](crate::dispatching) for the design
|
||||||
/// overview](crate::dispatching).
|
/// overview.
|
||||||
pub struct Dispatcher {
|
pub struct Dispatcher {
|
||||||
bot: Bot,
|
bot: Bot,
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@ use futures::future::BoxFuture;
|
||||||
|
|
||||||
/// An asynchronous handler of a stream of updates used in [`Dispatcher`].
|
/// An asynchronous handler of a stream of updates used in [`Dispatcher`].
|
||||||
///
|
///
|
||||||
/// See [the module-level documentation for the design
|
/// See the [module-level documentation](crate::dispatching) for the design
|
||||||
/// overview](crate::dispatching).
|
/// overview.
|
||||||
///
|
///
|
||||||
/// [`Dispatcher`]: crate::dispatching::Dispatcher
|
/// [`Dispatcher`]: crate::dispatching::Dispatcher
|
||||||
pub trait DispatcherHandler<Upd> {
|
pub trait DispatcherHandler<Upd> {
|
||||||
|
|
|
@ -5,6 +5,9 @@ use futures::{stream::BoxStream, Stream, StreamExt};
|
||||||
|
|
||||||
/// An extension trait to be used with [`DispatcherHandlerRx`].
|
/// An extension trait to be used with [`DispatcherHandlerRx`].
|
||||||
///
|
///
|
||||||
|
/// See the [module-level documentation](crate::dispatching) for the design
|
||||||
|
/// overview.
|
||||||
|
///
|
||||||
/// [`DispatcherHandlerRx`]: crate::dispatching::DispatcherHandlerRx
|
/// [`DispatcherHandlerRx`]: crate::dispatching::DispatcherHandlerRx
|
||||||
pub trait DispatcherHandlerRxExt {
|
pub trait DispatcherHandlerRxExt {
|
||||||
/// Extracts only text messages from this stream of arbitrary messages.
|
/// Extracts only text messages from this stream of arbitrary messages.
|
||||||
|
|
|
@ -12,8 +12,8 @@ use crate::{
|
||||||
|
|
||||||
/// A [`Dispatcher`]'s handler's context of a bot and an update.
|
/// A [`Dispatcher`]'s handler's context of a bot and an update.
|
||||||
///
|
///
|
||||||
/// See [the module-level documentation for the design
|
/// See the [module-level documentation](crate::dispatching) for the design
|
||||||
/// overview](crate::dispatching).
|
/// overview.
|
||||||
///
|
///
|
||||||
/// [`Dispatcher`]: crate::dispatching::Dispatcher
|
/// [`Dispatcher`]: crate::dispatching::Dispatcher
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
Loading…
Add table
Reference in a new issue