use chrono::{DateTime, Utc};
use grammers_session::types::PeerId;
use grammers_tl_types as tl;
use super::{Peer, PeerMap, Permissions, Restrictions};
use crate::{peer::User, utils};
#[derive(Clone, Debug, PartialEq)]
pub struct Normal {
date: i32,
inviter_id: Option<i64>,
}
#[derive(Clone, Debug, PartialEq)]
pub struct Creator {
permissions: Permissions,
rank: Option<String>,
}
#[derive(Clone, Debug, PartialEq)]
pub struct Admin {
can_edit: bool,
inviter_id: Option<i64>,
promoted_by: Option<i64>,
date: i32,
permissions: Permissions,
rank: Option<String>,
}
#[derive(Clone, Debug, PartialEq)]
pub struct Banned {
left: bool,
kicked_by: i64,
date: i32,
restrictions: Restrictions,
}
#[derive(Clone, Debug, PartialEq)]
pub struct Left {}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum Role {
User(Normal),
Creator(Creator),
Admin(Admin),
Banned(Banned),
Left(Left),
}
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct Participant {
pub user: User,
pub role: Role,
}
impl Normal {
pub fn date(&self) -> DateTime<Utc> {
utils::date(self.date)
}
pub fn inviter_id(&self) -> Option<PeerId> {
self.inviter_id.map(PeerId::user_unchecked)
}
}
impl Creator {
pub fn permissions(&self) -> &Permissions {
&self.permissions
}
pub fn rank(&self) -> Option<&str> {
self.rank.as_deref()
}
}
impl Admin {
pub fn can_edit(&self) -> bool {
self.can_edit
}
pub fn inviter_id(&self) -> Option<PeerId> {
self.inviter_id.map(PeerId::user_unchecked)
}
pub fn promoted_by(&self) -> Option<PeerId> {
self.promoted_by.map(PeerId::user_unchecked)
}
pub fn date(&self) -> DateTime<Utc> {
utils::date(self.date)
}
pub fn permissions(&self) -> &Permissions {
&self.permissions
}
pub fn rank(&self) -> Option<&str> {
self.rank.as_deref()
}
}
impl Banned {
pub fn left(&self) -> bool {
self.left
}
pub fn kicked_by(&self) -> PeerId {
PeerId::user_unchecked(self.kicked_by)
}
pub fn date(&self) -> DateTime<Utc> {
utils::date(self.date)
}
pub fn restrictions(&self) -> &Restrictions {
&self.restrictions
}
}
impl Participant {
pub(crate) fn from_raw_channel(
peers: &mut PeerMap,
participant: tl::enums::ChannelParticipant,
) -> Self {
use tl::enums::ChannelParticipant as P;
match participant {
P::Participant(p) => Self {
user: peers.take_user(p.user_id).unwrap(),
role: Role::User(Normal {
date: p.date,
inviter_id: None,
}),
},
P::ParticipantSelf(p) => Self {
user: peers.take_user(p.user_id).unwrap(),
role: Role::User(Normal {
date: p.date,
inviter_id: Some(p.inviter_id),
}),
},
P::Creator(p) => Self {
user: peers.take_user(p.user_id).unwrap(),
role: Role::Creator(Creator {
permissions: Permissions::from_raw(p.admin_rights.into()),
rank: p.rank,
}),
},
P::Admin(p) => Self {
user: peers.take_user(p.user_id).unwrap(),
role: Role::Admin(Admin {
can_edit: p.can_edit,
inviter_id: p.inviter_id,
promoted_by: Some(p.promoted_by),
date: p.date,
permissions: Permissions::from_raw(p.admin_rights.into()),
rank: p.rank,
}),
},
P::Banned(p) => Self {
user: match peers.take(PeerId::from(p.peer.clone())).unwrap() {
Peer::User(user) => user,
_ => todo!("figure out how to deal with non-user being banned"),
},
role: Role::Banned(Banned {
left: p.left,
kicked_by: p.kicked_by,
date: p.date,
restrictions: Restrictions::from_raw(p.banned_rights.into()),
}),
},
P::Left(p) => Self {
user: match peers.take(PeerId::from(p.peer.clone())).unwrap() {
Peer::User(user) => user,
_ => todo!("figure out how to deal with non-user leaving"),
},
role: Role::Left(Left {}),
},
}
}
pub(crate) fn from_raw_chat(
peers: &mut PeerMap,
participant: tl::enums::ChatParticipant,
) -> Self {
use tl::enums::ChatParticipant as P;
match participant {
P::Participant(p) => Self {
user: peers.take_user(p.user_id).unwrap(),
role: Role::User(Normal {
date: p.date,
inviter_id: Some(p.inviter_id),
}),
},
P::Creator(p) => Self {
user: peers.take_user(p.user_id).unwrap(),
role: Role::Creator(Creator {
permissions: Permissions::new_full(),
rank: None,
}),
},
P::Admin(p) => Self {
user: peers.take_user(p.user_id).unwrap(),
role: Role::Admin(Admin {
can_edit: true,
inviter_id: Some(p.inviter_id),
promoted_by: None,
date: p.date,
permissions: Permissions::new_full(),
rank: None,
}),
},
}
}
}