Skip to main content

ferogram_fsm/
key.rs

1// Copyright (c) Ankit Chaubey <ankitchaubey.dev@gmail.com>
2//
3// ferogram: async Telegram MTProto client in Rust
4// https://github.com/ankit-chaubey/ferogram
5//
6// Licensed under either the MIT License or the Apache License 2.0.
7// See the LICENSE-MIT or LICENSE-APACHE file in this repository:
8// https://github.com/ankit-chaubey/ferogram
9//
10// Feel free to use, modify, and share this code.
11// Please keep this notice when redistributing.
12
13/// Minimal view of an incoming message needed to build a [`StateKey`].
14///
15/// Implement this for your message type in the consumer crate so that
16/// `StateKey::from_message` can work without a direct dependency on
17/// `ferogram` itself.
18pub trait MessageLike {
19    fn sender_user_id(&self) -> Option<i64>;
20    fn chat_id(&self) -> i64;
21}
22
23/// Identifies which conversation slot to read/write state for.
24///
25/// The canonical strategy is per-user-per-chat so that the same user can
26/// have independent sessions in different chats simultaneously.
27#[derive(Debug, Clone, PartialEq, Eq, Hash)]
28pub struct StateKey {
29    /// The Telegram user ID, if applicable.
30    pub user_id: Option<i64>,
31    /// The Telegram chat ID.
32    pub chat_id: i64,
33}
34
35impl StateKey {
36    /// Construct a key from an incoming message using the given strategy.
37    pub fn from_message(msg: &impl MessageLike, strategy: StateKeyStrategy) -> Self {
38        match strategy {
39            StateKeyStrategy::PerUserPerChat => Self {
40                user_id: msg.sender_user_id(),
41                chat_id: msg.chat_id(),
42            },
43            StateKeyStrategy::PerUser => Self {
44                user_id: msg.sender_user_id(),
45                chat_id: 0,
46            },
47            StateKeyStrategy::PerChat => Self {
48                user_id: None,
49                chat_id: msg.chat_id(),
50            },
51        }
52    }
53}
54
55/// How the FSM key is composed from an incoming message.
56#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
57pub enum StateKeyStrategy {
58    /// Track state per user per chat (recommended for most bots). Default.
59    #[default]
60    PerUserPerChat,
61    /// Track state per user across all chats (global user session).
62    PerUser,
63    /// Track state per chat, regardless of sender (e.g. group games).
64    PerChat,
65}