use serde::{Deserialize, Serialize};
use crate::types::User;
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct ChatMember {
pub user: User,
#[serde(flatten)]
pub kind: ChatMemberKind,
}
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(tag = "status")]
pub enum ChatMemberKind {
Creator(Creator),
Administrator(Administrator),
Member,
Restricted(Restricted),
Left,
Kicked(Kicked),
}
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct Creator {
pub custom_title: Option<String>,
pub is_anonymous: bool,
}
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct Administrator {
pub custom_title: Option<String>,
pub is_anonymous: bool,
pub can_be_edited: bool,
pub can_manage_chat: bool,
pub can_change_info: bool,
pub can_post_messages: Option<bool>,
pub can_edit_messages: Option<bool>,
pub can_delete_messages: bool,
pub can_manage_voice_chats: bool,
pub can_invite_users: bool,
pub can_restrict_members: bool,
pub can_pin_messages: Option<bool>,
pub can_promote_members: bool,
}
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct Restricted {
pub until_date: i32,
pub can_send_messages: bool,
pub can_send_media_messages: bool,
pub can_send_other_messages: bool,
pub can_add_web_page_previews: bool,
}
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct Kicked {
pub until_date: i32,
}
impl ChatMember {
pub fn status(&self) -> ChatMemberStatus {
match &self.kind {
ChatMemberKind::Creator(_) => ChatMemberStatus::Creator,
ChatMemberKind::Administrator(_) => ChatMemberStatus::Administrator,
ChatMemberKind::Member => ChatMemberStatus::Member,
ChatMemberKind::Restricted(_) => ChatMemberStatus::Restricted,
ChatMemberKind::Left => ChatMemberStatus::Left,
ChatMemberKind::Kicked(_) => ChatMemberStatus::Kicked,
}
}
}
impl ChatMemberKind {
pub fn custom_title(&self) -> Option<&str> {
match &self {
Self::Administrator(Administrator { custom_title, .. })
| Self::Creator(Creator { custom_title, .. }) => custom_title.as_deref(),
Self::Member | Self::Restricted(_) | Self::Left | Self::Kicked(_) => None,
}
}
pub fn until_date(&self) -> Option<i32> {
match &self {
Self::Creator(_) | Self::Administrator(_) | Self::Member | Self::Left => None,
Self::Restricted(Restricted { until_date, .. })
| Self::Kicked(Kicked { until_date, .. }) => Some(*until_date),
}
}
pub fn can_be_edited(&self) -> Option<bool> {
match &self {
Self::Administrator(Administrator { can_be_edited, .. }) => Some(*can_be_edited),
Self::Creator(_)
| Self::Member
| Self::Restricted(_)
| Self::Left
| Self::Kicked(_) => None,
}
}
pub fn can_manage_chat(&self) -> Option<bool> {
match &self {
Self::Administrator(Administrator {
can_manage_chat, ..
}) => Some(*can_manage_chat),
Self::Creator(_)
| Self::Member
| Self::Restricted(_)
| Self::Left
| Self::Kicked(_) => None,
}
}
pub fn can_change_info(&self) -> Option<bool> {
match &self {
Self::Administrator(Administrator {
can_change_info, ..
}) => Some(*can_change_info),
Self::Creator(_)
| Self::Member
| Self::Restricted(_)
| Self::Left
| Self::Kicked(_) => None,
}
}
pub fn can_post_messages(&self) -> Option<bool> {
match &self {
Self::Administrator(Administrator {
can_post_messages, ..
}) => *can_post_messages,
Self::Creator(_)
| Self::Member
| Self::Restricted(_)
| Self::Left
| Self::Kicked(_) => None,
}
}
pub fn can_edit_messages(&self) -> Option<bool> {
match &self {
Self::Administrator(Administrator {
can_edit_messages, ..
}) => *can_edit_messages,
Self::Creator(_)
| Self::Member
| Self::Restricted(_)
| Self::Left
| Self::Kicked(_) => None,
}
}
pub fn can_delete_messages(&self) -> Option<bool> {
match &self {
Self::Administrator(Administrator {
can_delete_messages,
..
}) => Some(*can_delete_messages),
Self::Creator(_)
| Self::Member
| Self::Restricted(_)
| Self::Left
| Self::Kicked(_) => None,
}
}
pub fn can_manage_voice_chats(&self) -> Option<bool> {
match &self {
Self::Administrator(Administrator {
can_manage_voice_chats,
..
}) => Some(*can_manage_voice_chats),
Self::Creator(_)
| Self::Member
| Self::Restricted(_)
| Self::Left
| Self::Kicked(_) => None,
}
}
pub fn can_invite_users(&self) -> Option<bool> {
match &self {
Self::Administrator(Administrator {
can_invite_users, ..
}) => Some(*can_invite_users),
Self::Creator(_)
| Self::Member
| Self::Restricted(_)
| Self::Left
| Self::Kicked(_) => None,
}
}
pub fn can_restrict_members(&self) -> Option<bool> {
match &self {
Self::Administrator(Administrator {
can_restrict_members,
..
}) => Some(*can_restrict_members),
Self::Creator(_)
| Self::Member
| Self::Restricted(_)
| Self::Left
| Self::Kicked(_) => None,
}
}
pub fn can_pin_messages(&self) -> Option<bool> {
match &self {
Self::Administrator(Administrator {
can_pin_messages, ..
}) => *can_pin_messages,
Self::Creator(_)
| Self::Member
| Self::Restricted(_)
| Self::Left
| Self::Kicked(_) => None,
}
}
pub fn can_promote_members(&self) -> Option<bool> {
match &self {
Self::Administrator(Administrator {
can_promote_members,
..
}) => Some(*can_promote_members),
Self::Creator(_)
| Self::Member
| Self::Restricted(_)
| Self::Left
| Self::Kicked(_) => None,
}
}
pub fn can_send_messages(&self) -> Option<bool> {
match &self {
Self::Restricted(Restricted {
can_send_messages, ..
}) => Some(*can_send_messages),
Self::Creator(_)
| Self::Administrator(_)
| Self::Member
| Self::Left
| Self::Kicked(_) => None,
}
}
pub fn can_send_media_messages(&self) -> Option<bool> {
match &self {
Self::Restricted(Restricted {
can_send_media_messages,
..
}) => Some(*can_send_media_messages),
Self::Creator(_)
| Self::Administrator(_)
| Self::Member
| Self::Left
| Self::Kicked(_) => None,
}
}
pub fn can_send_other_messages(&self) -> Option<bool> {
match &self {
Self::Restricted(Restricted {
can_send_other_messages,
..
}) => Some(*can_send_other_messages),
Self::Creator(_)
| Self::Administrator(_)
| Self::Member
| Self::Left
| Self::Kicked(_) => None,
}
}
pub fn can_add_web_page_previews(&self) -> Option<bool> {
match &self {
Self::Restricted(Restricted {
can_add_web_page_previews,
..
}) => Some(*can_add_web_page_previews),
Self::Creator(_)
| Self::Administrator(_)
| Self::Member
| Self::Left
| Self::Kicked(_) => None,
}
}
}
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ChatMemberStatus {
Creator,
Administrator,
Member,
Restricted,
Left,
Kicked,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deserialize() {
let json = r#"{
"user":{
"id":1029940401,
"is_bot":false,
"first_name":"First",
"last_name":"Last",
"username":"fl",
"language_code":"en"
},
"status":"administrator",
"is_anonymous": false,
"can_be_edited": false,
"can_manage_chat": true,
"can_change_info": true,
"can_delete_messages": true,
"can_manage_voice_chats": true,
"can_invite_users": true,
"can_restrict_members": true,
"can_pin_messages": true,
"can_promote_members": true
}"#;
let expected = ChatMember {
user: User {
id: 1029940401,
is_bot: false,
first_name: "First".to_string(),
last_name: Some("Last".to_string()),
username: Some("fl".to_string()),
language_code: Some("en".to_string()),
},
kind: ChatMemberKind::Administrator(Administrator {
custom_title: None,
is_anonymous: false,
can_be_edited: false,
can_manage_chat: true,
can_change_info: true,
can_post_messages: None,
can_edit_messages: None,
can_delete_messages: true,
can_manage_voice_chats: true,
can_invite_users: true,
can_restrict_members: true,
can_pin_messages: Some(true),
can_promote_members: true,
}),
};
let actual = serde_json::from_str::<ChatMember>(&json).unwrap();
assert_eq!(actual, expected)
}
}