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}