1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
use crate::dispatching::{dialogue::DialogueStage, UpdateWithCx};
use futures::future::BoxFuture;
use teloxide_core::types::Message;

/// Represents a transition function of a dialogue FSM.
pub trait Transition: Sized {
    type Aux;
    type Error;
    type Requester;

    /// Turns itself into another state, depending on the input message.
    ///
    /// `aux` will be passed to each subtransition function.
    fn react(
        self,
        cx: TransitionIn<Self::Requester>,
        aux: Self::Aux,
    ) -> BoxFuture<'static, TransitionOut<Self, Self::Error>>;
}

/// Like [`Transition`], but from `StateN` -> `Dialogue`.
///
/// [`Transition`]: crate::dispatching::dialogue::Transition
pub trait Subtransition
where
    Self::Dialogue: Transition<Aux = Self::Aux>,
{
    type Aux;
    type Dialogue;
    type Error;
    type Requester;

    /// Turns itself into another state, depending on the input message.
    ///
    /// `aux` is something that is provided by the call side, for example,
    /// message's text.
    fn react(
        self,
        cx: TransitionIn<Self::Requester>,
        aux: Self::Aux,
    ) -> BoxFuture<'static, TransitionOut<Self::Dialogue, Self::Error>>;
}

/// A type returned from a FSM subtransition function.
///
/// Now it is used only inside `#[teloxide(subtransition)]` for type inference.
#[doc(hidden)]
pub trait SubtransitionOutputType {
    type Output;
    type Error;
}

impl<D, E> SubtransitionOutputType for TransitionOut<D, E> {
    type Output = D;
    type Error = E;
}

/// An input passed into a FSM (sub)transition function.
pub type TransitionIn<R> = UpdateWithCx<R, Message>;

/// A type returned from a FSM (sub)transition function.
pub type TransitionOut<D, E = crate::RequestError> = Result<DialogueStage<D>, E>;