1use chrono::{DateTime, Utc};
10use grammers_session::types::PeerId;
11use grammers_tl_types as tl;
12
13use super::{Peer, PeerMap, Permissions, Restrictions};
14use crate::{peer::User, utils};
15
16#[derive(Clone, Debug, PartialEq)]
18pub struct Normal {
19 date: i32,
20 inviter_id: Option<i64>,
21}
22
23#[derive(Clone, Debug, PartialEq)]
25pub struct Creator {
26 permissions: Permissions,
27 rank: Option<String>,
28}
29
30#[derive(Clone, Debug, PartialEq)]
32pub struct Admin {
33 can_edit: bool,
34 inviter_id: Option<i64>,
35 promoted_by: Option<i64>,
36 date: i32,
37 permissions: Permissions,
38 rank: Option<String>,
39}
40
41#[derive(Clone, Debug, PartialEq)]
43pub struct Banned {
44 left: bool,
45 kicked_by: i64,
46 date: i32,
47 restrictions: Restrictions,
48}
49
50#[derive(Clone, Debug, PartialEq)]
52pub struct Left {}
53
54#[derive(Clone, Debug, PartialEq)]
56#[non_exhaustive]
57pub enum Role {
58 User(Normal),
59 Creator(Creator),
60 Admin(Admin),
61 Banned(Banned),
62 Left(Left),
63}
64
65#[derive(Clone, Debug)]
67#[non_exhaustive]
68pub struct Participant {
69 pub user: User,
70 pub role: Role,
71}
72
73impl Normal {
74 pub fn date(&self) -> DateTime<Utc> {
76 utils::date(self.date)
77 }
78
79 pub fn inviter_id(&self) -> Option<PeerId> {
81 self.inviter_id.map(PeerId::user_unchecked)
82 }
83}
84
85impl Creator {
86 pub fn permissions(&self) -> &Permissions {
88 &self.permissions
89 }
90
91 pub fn rank(&self) -> Option<&str> {
93 self.rank.as_deref()
94 }
95}
96
97impl Admin {
98 pub fn can_edit(&self) -> bool {
99 self.can_edit
100 }
101
102 pub fn inviter_id(&self) -> Option<PeerId> {
104 self.inviter_id.map(PeerId::user_unchecked)
105 }
106
107 pub fn promoted_by(&self) -> Option<PeerId> {
109 self.promoted_by.map(PeerId::user_unchecked)
110 }
111
112 pub fn date(&self) -> DateTime<Utc> {
113 utils::date(self.date)
114 }
115
116 pub fn permissions(&self) -> &Permissions {
118 &self.permissions
119 }
120
121 pub fn rank(&self) -> Option<&str> {
123 self.rank.as_deref()
124 }
125}
126
127impl Banned {
128 pub fn left(&self) -> bool {
129 self.left
130 }
131
132 pub fn kicked_by(&self) -> PeerId {
134 PeerId::user_unchecked(self.kicked_by)
135 }
136
137 pub fn date(&self) -> DateTime<Utc> {
138 utils::date(self.date)
139 }
140
141 pub fn restrictions(&self) -> &Restrictions {
143 &self.restrictions
144 }
145}
146
147impl Participant {
148 pub(crate) fn from_raw_channel(
149 peers: &mut PeerMap,
150 participant: tl::enums::ChannelParticipant,
151 ) -> Self {
152 use tl::enums::ChannelParticipant as P;
153
154 match participant {
155 P::Participant(p) => Self {
156 user: peers.take_user(p.user_id).unwrap(),
157 role: Role::User(Normal {
158 date: p.date,
159 inviter_id: None,
160 }),
161 },
162 P::ParticipantSelf(p) => Self {
163 user: peers.take_user(p.user_id).unwrap(),
164 role: Role::User(Normal {
165 date: p.date,
166 inviter_id: Some(p.inviter_id),
167 }),
168 },
169 P::Creator(p) => Self {
170 user: peers.take_user(p.user_id).unwrap(),
171 role: Role::Creator(Creator {
172 permissions: Permissions::from_raw(p.admin_rights.into()),
173 rank: p.rank,
174 }),
175 },
176 P::Admin(p) => Self {
177 user: peers.take_user(p.user_id).unwrap(),
178 role: Role::Admin(Admin {
179 can_edit: p.can_edit,
180 inviter_id: p.inviter_id,
181 promoted_by: Some(p.promoted_by),
182 date: p.date,
183 permissions: Permissions::from_raw(p.admin_rights.into()),
184 rank: p.rank,
185 }),
186 },
187 P::Banned(p) => Self {
188 user: match peers.take(PeerId::from(p.peer.clone())).unwrap() {
189 Peer::User(user) => user,
190 _ => todo!("figure out how to deal with non-user being banned"),
191 },
192 role: Role::Banned(Banned {
193 left: p.left,
194 kicked_by: p.kicked_by,
195 date: p.date,
196 restrictions: Restrictions::from_raw(p.banned_rights.into()),
197 }),
198 },
199 P::Left(p) => Self {
200 user: match peers.take(PeerId::from(p.peer.clone())).unwrap() {
201 Peer::User(user) => user,
202 _ => todo!("figure out how to deal with non-user leaving"),
203 },
204 role: Role::Left(Left {}),
205 },
206 }
207 }
208
209 pub(crate) fn from_raw_chat(
210 peers: &mut PeerMap,
211 participant: tl::enums::ChatParticipant,
212 ) -> Self {
213 use tl::enums::ChatParticipant as P;
214
215 match participant {
216 P::Participant(p) => Self {
217 user: peers.take_user(p.user_id).unwrap(),
218 role: Role::User(Normal {
219 date: p.date,
220 inviter_id: Some(p.inviter_id),
221 }),
222 },
223 P::Creator(p) => Self {
224 user: peers.take_user(p.user_id).unwrap(),
225 role: Role::Creator(Creator {
226 permissions: Permissions::new_full(),
227 rank: None,
228 }),
229 },
230 P::Admin(p) => Self {
231 user: peers.take_user(p.user_id).unwrap(),
232 role: Role::Admin(Admin {
233 can_edit: true,
234 inviter_id: Some(p.inviter_id),
235 promoted_by: None,
236 date: p.date,
237 permissions: Permissions::new_full(),
238 rank: None,
239 }),
240 },
241 }
242 }
243}