Skip to content

Commit

Permalink
Add new variants to Strategy to use with business connection
Browse files Browse the repository at this point in the history
  • Loading branch information
Desiders committed Apr 28, 2024
1 parent 36caecc commit f845f41
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 20 deletions.
10 changes: 9 additions & 1 deletion telers/src/fsm/storage/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,25 @@ pub struct StorageKey {
pub chat_id: i64,
pub user_id: i64,
pub message_thread_id: Option<i64>,
pub business_connection_id: Option<String>,
pub destiny: &'static str,
}

impl StorageKey {
#[must_use]
pub fn new(bot_id: i64, chat_id: i64, user_id: i64, message_thread_id: Option<i64>) -> Self {
pub fn new(
bot_id: i64,
chat_id: i64,
user_id: i64,
message_thread_id: Option<i64>,
business_connection_id: Option<String>,
) -> Self {
Self {
bot_id,
chat_id,
user_id,
message_thread_id,
business_connection_id,
destiny: DEFAULT_DESTINY,
}
}
Expand Down
8 changes: 4 additions & 4 deletions telers/src/fsm/storage/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,8 +378,8 @@ mod tests {
async fn test_state() {
let storage = Memory::default();

let key1 = StorageKey::new(0, 1, 2, None);
let key2 = StorageKey::new(2, 1, 0, None);
let key1 = StorageKey::new(0, 1, 2, None, None);
let key2 = StorageKey::new(2, 1, 0, None, None);

assert_eq!(storage.get_state(&key1).await.unwrap(), None);
assert_eq!(storage.get_state(&key2).await.unwrap(), None);
Expand Down Expand Up @@ -427,8 +427,8 @@ mod tests {
async fn test_data() {
let storage = Memory::default();

let key1 = StorageKey::new(0, 1, 2, None);
let key2 = StorageKey::new(2, 1, 0, None);
let key1 = StorageKey::new(0, 1, 2, None, None);
let key2 = StorageKey::new(2, 1, 0, None, None);

assert_eq!(
storage.get_data::<Box<str>>(&key1).await.unwrap(),
Expand Down
4 changes: 4 additions & 0 deletions telers/src/fsm/storage/redis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ impl KeyBuilder for KeyBuilderImpl {
if let Some(message_thread_id) = &message_thread_id {
parts.push(message_thread_id);
}
if let Some(ref business_connection_id) = key.business_connection_id {
parts.push(business_connection_id);
}

parts.push(&user_id);
parts.push(part.as_str());

Expand Down
92 changes: 82 additions & 10 deletions telers/src/fsm/strategy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,35 @@ use std::fmt::{self, Display};
/// Strategy for storing and retrieving data.
///
/// # Variants
/// * [`Strategy::UserInChat`] - `user_id` + `chat_id`.
/// * [`Strategy::UserInChat`] - `user_id` + `chat_id`.\
/// If you use `UserInChat` strategy, you have possible to store different state for user+chat pairs,
/// so each user in each chat will have its own state.
/// * [`Strategy::Chat`] - `chat_id` + `chat_id`.
/// * [`Strategy::Chat`] - `chat_id` + `chat_id`.\
/// If you use `Chat` strategy, then all users in the chat will have the same state.
/// * [`Strategy::GlobalUser`] - `user_id` + `user_id`.
/// * [`Strategy::GlobalUser`] - `user_id` + `user_id`.\
/// If you use `GlobalUser` strategy, then the user will have the same state in all chats,
/// so each user will have its own state in all chats.
/// * [`Strategy::UserInThread`] - `user_id` + `chat_id` + `message_thread_id`.
/// * [`Strategy::UserInThread`] - `user_id` + `chat_id` + `message_thread_id`.\
/// If you use `UserInThread` strategy, you have possible to store different state for user+chat+thread pairs,
/// so each user in each thread in each chat will have its own state.
/// * [`Strategy::ChatInThread`] - `chat_id` + `chat_id` + `message_thread_id`.
/// If you use `ChatInThread` strategy, you have possible to store different state for chat+thread pairs,
/// * [`Strategy::ChatThread`] - `chat_id` + `chat_id` + `message_thread_id`.\
/// If you use `ChatThread` strategy, you have possible to store different state for chat+thread pairs,
/// so each thread in each chat will have its own state.
///
/// If you need to have different states for business connections, you can use strategies with `business_connection_id` field.\
/// Strategies with `business_connection_id` field:
/// * [`Strategy::UserInChatAndConnection`] - `user_id` + `chat_id` + `business_connection_id`.\
/// Identical to `UserInChat`, but with an additional `business_connection_id` field.
/// * [`Strategy::ChatAndConnection`] - `chat_id` + `chat_id` + `business_connection_id`.\
/// Identical to `Chat`, but with an additional `business_connection_id` field.
/// * [`Strategy::GlobalUserAndConnection`] - `user_id` + `user_id` + `business_connection_id`.\
/// Identical to `GlobalUser`, but with an additional `business_connection_id` field.
/// * [`Strategy::UserInThreadAndConnection`] - `user_id` + `chat_id` + `message_thread_id` + `business_connection_id`.\
/// Identical to `UserInThread`, but with an additional `business_connection_id` field.
/// * [`Strategy::ChatThreadAndConnection`] - `chat_id` + `chat_id` + `message_thread_id` + `business_connection_id`.\
/// Identical to `ChatThread`, but with an additional `business_connection_id` field.
///
/// # Notes
/// In case of direct messages, `chat_id` and `user_id` will be equal, so all strategies will work the same way.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Strategy {
Expand All @@ -30,7 +44,18 @@ pub enum Strategy {
/// `user_id` + `chat_id` + `message_thread_id`
UserInThread,
/// `chat_id` + `chat_id` + `message_thread_id`
ChatInThread,
ChatThread,

/// `user_id` + `chat_id` + `business_connection_id`
UserInChatAndConnection,
/// `chat_id` + `chat_id` + `business_connection_id`
ChatAndConnection,
/// `user_id` + `user_id` + `business_connection_id`
GlobalUserAndConnection,
/// `user_id` + `chat_id` + `message_thread_id` + `business_connection_id`
UserInThreadAndConnection,
/// `chat_id` + `chat_id` + `message_thread_id` + `business_connection_id`
ChatThreadAndConnection,
}

impl Display for Strategy {
Expand All @@ -54,7 +79,12 @@ impl Strategy {
Strategy::Chat => "chat",
Strategy::GlobalUser => "global_user",
Strategy::UserInThread => "user_in_thread",
Strategy::ChatInThread => "chat_in_thread",
Strategy::ChatThread => "chat_thread",
Strategy::UserInChatAndConnection => "user_in_chat_and_connection",
Strategy::ChatAndConnection => "chat_and_connection",
Strategy::GlobalUserAndConnection => "global_user_and_connection",
Strategy::UserInThreadAndConnection => "user_in_thread_and_connection",
Strategy::ChatThreadAndConnection => "chat_thread_and_connection",
}
}
}
Expand All @@ -63,37 +93,79 @@ pub struct IdPair {
pub chat_id: i64,
pub user_id: i64,
pub message_thread_id: Option<i64>,
pub business_connection_id: Option<String>,
}

impl Strategy {
/// Apply strategy to `chat_id`, `user_id` and `message_thread_id`
#[must_use]
pub fn apply(&self, chat_id: i64, user_id: i64, message_thread_id: Option<i64>) -> IdPair {
pub fn apply(
&self,
chat_id: i64,
user_id: i64,
message_thread_id: Option<i64>,
business_connection_id: Option<String>,
) -> IdPair {
match self {
Strategy::UserInChat => IdPair {
chat_id,
user_id,
message_thread_id: None,
business_connection_id: None,
},
Strategy::UserInChatAndConnection => IdPair {
chat_id,
user_id,
message_thread_id: None,
business_connection_id,
},
Strategy::Chat => IdPair {
chat_id,
user_id: chat_id,
message_thread_id: None,
business_connection_id: None,
},
Strategy::ChatAndConnection => IdPair {
chat_id,
user_id: chat_id,
message_thread_id: None,
business_connection_id,
},
Strategy::GlobalUser => IdPair {
chat_id: user_id,
user_id,
message_thread_id: None,
business_connection_id: None,
},
Strategy::GlobalUserAndConnection => IdPair {
chat_id: user_id,
user_id,
message_thread_id: None,
business_connection_id,
},
Strategy::UserInThread => IdPair {
chat_id,
user_id,
message_thread_id,
business_connection_id: None,
},
Strategy::UserInThreadAndConnection => IdPair {
chat_id,
user_id,
message_thread_id,
business_connection_id,
},
Strategy::ChatThread => IdPair {
chat_id,
user_id: chat_id,
message_thread_id,
business_connection_id: None,
},
Strategy::ChatInThread => IdPair {
Strategy::ChatThreadAndConnection => IdPair {
chat_id,
user_id: chat_id,
message_thread_id,
business_connection_id,
},
}
}
Expand Down
26 changes: 21 additions & 5 deletions telers/src/middlewares/outer/fsm_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,22 @@ where
let user = context.get("event_user");
let chat = context.get("event_chat");
let message_thread_id = context.get("event_message_thread_id");
let business_connection_id = context.get("event_business_connection_id");

let user_id = user.and_then(|user| user.downcast_ref().map(|user: &User| user.id));
let chat_id = chat.and_then(|chat| chat.downcast_ref().map(|chat: &Chat| chat.id()));
let message_thread_id = message_thread_id
.and_then(|message_thread_id| message_thread_id.downcast_ref().copied());

self.resolve_context(bot_id, chat_id, user_id, message_thread_id)
let business_connection_id = business_connection_id
.and_then(|business_connection_id| business_connection_id.downcast_ref().cloned());

self.resolve_context(
bot_id,
chat_id,
user_id,
message_thread_id,
business_connection_id,
)
}

#[must_use]
Expand All @@ -99,17 +108,22 @@ where
chat_id: Option<i64>,
user_id: Option<i64>,
message_thread_id: Option<i64>,
business_connection_id: Option<String>,
) -> Option<Context<S>> {
user_id.map(|user_id| {
let id_pair =
self.strategy
.apply(chat_id.unwrap_or(user_id), user_id, message_thread_id);
let id_pair = self.strategy.apply(
chat_id.unwrap_or(user_id),
user_id,
message_thread_id,
business_connection_id,
);

self.get_context(
bot_id,
id_pair.chat_id,
id_pair.user_id,
id_pair.message_thread_id,
id_pair.business_connection_id,
)
})
}
Expand All @@ -121,6 +135,7 @@ where
chat_id: i64,
user_id: i64,
message_thread_id: Option<i64>,
business_connection_id: Option<String>,
) -> Context<S> {
Context::new(
self.storage.clone(),
Expand All @@ -129,6 +144,7 @@ where
chat_id,
user_id,
message_thread_id,
business_connection_id,
destiny: self.destiny,
},
)
Expand Down
7 changes: 7 additions & 0 deletions telers/src/middlewares/outer/user_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ where
context.insert("event_message_thread_id", Box::new(message_thread_id));
}

if let Some(business_connection_id) = update.business_connection_id() {
context.insert(
"event_business_connection_id",
Box::new(business_connection_id.to_owned()),
);
}

Ok((request, EventReturn::default()))
}
}
Expand Down

0 comments on commit f845f41

Please sign in to comment.