use std::fmt::{self, Display};
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
pub enum Strategy {
#[default]
UserInChat,
Chat,
GlobalUser,
UserInThread,
ChatThread,
UserInChatAndConnection,
ChatAndConnection,
GlobalUserAndConnection,
UserInThreadAndConnection,
ChatThreadAndConnection,
}
impl Display for Strategy {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}
impl Strategy {
#[inline]
#[must_use]
pub const fn as_str(&self) -> &'static str {
match self {
Strategy::UserInChat => "user_in_chat",
Strategy::Chat => "chat",
Strategy::GlobalUser => "global_user",
Strategy::UserInThread => "user_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",
}
}
}
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 {
#[inline]
#[must_use]
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::ChatThreadAndConnection => IdPair {
chat_id,
user_id: chat_id,
message_thread_id,
business_connection_id,
},
}
}
}
#[cfg(test)]
mod tests {
use super::Strategy;
#[test]
fn default_is_user_in_chat() {
assert_eq!(Strategy::default(), Strategy::UserInChat);
}
#[test]
fn display_matches_as_str() {
assert_eq!(Strategy::UserInChat.as_str(), "user_in_chat");
assert_eq!(
Strategy::ChatThreadAndConnection.as_str(),
"chat_thread_and_connection"
);
assert_eq!(Strategy::GlobalUser.to_string(), "global_user");
}
fn applied(strategy: &Strategy) -> (i64, i64, Option<i64>, Option<String>) {
let pair = strategy.apply(1, 2, Some(3), Some("bc".to_owned()));
(
pair.chat_id,
pair.user_id,
pair.message_thread_id,
pair.business_connection_id,
)
}
#[test]
fn user_in_chat_keeps_chat_and_user_drops_thread_and_connection() {
assert_eq!(applied(&Strategy::UserInChat), (1, 2, None, None));
assert_eq!(
applied(&Strategy::UserInChatAndConnection),
(1, 2, None, Some("bc".to_owned()))
);
}
#[test]
fn chat_uses_chat_id_for_both_ids() {
assert_eq!(applied(&Strategy::Chat), (1, 1, None, None));
assert_eq!(
applied(&Strategy::ChatAndConnection),
(1, 1, None, Some("bc".to_owned()))
);
}
#[test]
fn global_user_uses_user_id_for_both_ids() {
assert_eq!(applied(&Strategy::GlobalUser), (2, 2, None, None));
assert_eq!(
applied(&Strategy::GlobalUserAndConnection),
(2, 2, None, Some("bc".to_owned()))
);
}
#[test]
fn user_in_thread_keeps_thread() {
assert_eq!(applied(&Strategy::UserInThread), (1, 2, Some(3), None));
assert_eq!(
applied(&Strategy::UserInThreadAndConnection),
(1, 2, Some(3), Some("bc".to_owned()))
);
}
#[test]
fn chat_thread_uses_chat_id_and_keeps_thread() {
assert_eq!(applied(&Strategy::ChatThread), (1, 1, Some(3), None));
assert_eq!(
applied(&Strategy::ChatThreadAndConnection),
(1, 1, Some(3), Some("bc".to_owned()))
);
}
}