use std::fmt;
use grammers_session::types::{PeerAuth, PeerId, PeerInfo, PeerRef};
use grammers_tl_types as tl;
use crate::Client;
#[derive(Clone)]
pub struct Group {
pub raw: tl::enums::Chat,
pub(crate) client: Client,
}
impl fmt::Debug for Group {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.raw.fmt(f)
}
}
impl Group {
pub fn from_raw(client: &Client, chat: tl::enums::Chat) -> Self {
use tl::enums::Chat as C;
match chat {
C::Empty(_) | C::Chat(_) | C::Forbidden(_) => Self {
raw: chat,
client: client.clone(),
},
C::Channel(ref channel) => {
if channel.broadcast {
panic!("tried to create megagroup channel from broadcast");
} else {
Self {
raw: chat,
client: client.clone(),
}
}
}
C::ChannelForbidden(ref channel) => {
if channel.broadcast {
panic!("tried to create megagroup channel from broadcast");
} else {
Self {
raw: chat,
client: client.clone(),
}
}
}
}
}
pub fn id(&self) -> PeerId {
use tl::enums::Chat;
match &self.raw {
Chat::Empty(chat) => PeerId::chat_unchecked(chat.id),
Chat::Chat(chat) => PeerId::chat_unchecked(chat.id),
Chat::Forbidden(chat) => PeerId::chat_unchecked(chat.id),
Chat::Channel(channel) => PeerId::channel_unchecked(channel.id),
Chat::ChannelForbidden(channel) => PeerId::channel_unchecked(channel.id),
}
}
pub(crate) fn auth(&self) -> Option<PeerAuth> {
use tl::enums::Chat;
Some(match &self.raw {
Chat::Empty(_) => PeerAuth::default(),
Chat::Chat(_) => PeerAuth::default(),
Chat::Forbidden(_) => PeerAuth::default(),
Chat::Channel(channel) => {
return channel
.access_hash
.filter(|_| !channel.min)
.map(PeerAuth::from_hash);
}
Chat::ChannelForbidden(channel) => PeerAuth::from_hash(channel.access_hash),
})
}
pub async fn to_ref(&self) -> Option<PeerRef> {
let id = self.id();
match self.auth() {
Some(auth) => Some(PeerRef { id, auth }),
None => self.client.0.session.peer_ref(id).await,
}
}
pub fn title(&self) -> Option<&str> {
use tl::enums::Chat;
match &self.raw {
Chat::Empty(_) => None,
Chat::Chat(chat) => Some(chat.title.as_str()),
Chat::Forbidden(chat) => Some(chat.title.as_str()),
Chat::Channel(channel) => Some(channel.title.as_str()),
Chat::ChannelForbidden(channel) => Some(channel.title.as_str()),
}
}
pub fn username(&self) -> Option<&str> {
use tl::enums::Chat;
match &self.raw {
Chat::Empty(_) | Chat::Chat(_) | Chat::Forbidden(_) | Chat::ChannelForbidden(_) => None,
Chat::Channel(channel) => channel.username.as_deref(),
}
}
pub fn usernames(&self) -> Vec<&str> {
use tl::enums::Chat;
match &self.raw {
Chat::Empty(_) | Chat::Chat(_) | Chat::Forbidden(_) | Chat::ChannelForbidden(_) => {
Vec::new()
}
Chat::Channel(channel) => {
channel
.usernames
.as_deref()
.map_or(Vec::new(), |usernames| {
usernames
.iter()
.map(|username| match username {
tl::enums::Username::Username(username) => {
username.username.as_ref()
}
})
.collect()
})
}
}
}
pub fn photo(&self) -> Option<&tl::types::ChatPhoto> {
match &self.raw {
tl::enums::Chat::Empty(_)
| tl::enums::Chat::Forbidden(_)
| tl::enums::Chat::ChannelForbidden(_) => None,
tl::enums::Chat::Chat(chat) => match &chat.photo {
tl::enums::ChatPhoto::Empty => None,
tl::enums::ChatPhoto::Photo(photo) => Some(photo),
},
tl::enums::Chat::Channel(channel) => match &channel.photo {
tl::enums::ChatPhoto::Empty => None,
tl::enums::ChatPhoto::Photo(photo) => Some(photo),
},
}
}
pub fn is_megagroup(&self) -> bool {
use tl::enums::Chat as C;
match &self.raw {
C::Empty(_) | C::Chat(_) | C::Forbidden(_) => false,
C::Channel(_) | C::ChannelForbidden(_) => true,
}
}
pub fn requires_join_request(&self) -> bool {
use tl::enums::Chat;
match &self.raw {
Chat::Empty(_) | Chat::Chat(_) | Chat::Forbidden(_) | Chat::ChannelForbidden(_) => {
false
}
Chat::Channel(channel) => channel.join_request,
}
}
}
impl From<Group> for PeerInfo {
#[inline]
fn from(group: Group) -> Self {
<Self as From<&Group>>::from(&group)
}
}
impl<'a> From<&'a Group> for PeerInfo {
fn from(group: &'a Group) -> Self {
<Self as From<&'a tl::enums::Chat>>::from(&group.raw)
}
}