Skip to main content

grammers_client/peer/
participant.rs

1// Copyright 2020 - developers of the `grammers` project.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use 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/// Chat participant with default permissions.
17#[derive(Clone, Debug, PartialEq)]
18pub struct Normal {
19    date: i32,
20    inviter_id: Option<i64>,
21}
22
23/// Chat participant that created the chat itself.
24#[derive(Clone, Debug, PartialEq)]
25pub struct Creator {
26    permissions: Permissions,
27    rank: Option<String>,
28}
29
30/// Chat participant promoted to administrator.
31#[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/// Chat participant demoted to have restrictions.
42#[derive(Clone, Debug, PartialEq)]
43pub struct Banned {
44    left: bool,
45    kicked_by: i64,
46    date: i32,
47    restrictions: Restrictions,
48}
49
50/// Chat participant no longer present in the chat.
51#[derive(Clone, Debug, PartialEq)]
52pub struct Left {}
53
54/// Participant role within a group or channel.
55#[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/// User and their role within the group or channel.
66#[derive(Clone, Debug)]
67#[non_exhaustive]
68pub struct Participant {
69    pub user: User,
70    pub role: Role,
71}
72
73impl Normal {
74    /// Date when the participant joined.
75    pub fn date(&self) -> DateTime<Utc> {
76        utils::date(self.date)
77    }
78
79    /// Identifier of the person that invited the participant into the chat, if known.
80    pub fn inviter_id(&self) -> Option<PeerId> {
81        self.inviter_id.map(PeerId::user_unchecked)
82    }
83}
84
85impl Creator {
86    /// Permissions this administrator has in the chat.
87    pub fn permissions(&self) -> &Permissions {
88        &self.permissions
89    }
90
91    /// Custom administrator title.
92    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    /// Identifier of the person that invited the participant into the chat, if known.
103    pub fn inviter_id(&self) -> Option<PeerId> {
104        self.inviter_id.map(PeerId::user_unchecked)
105    }
106
107    /// Identifier of the person that promoted the participant, if known.
108    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    /// Permissions this administrator has in the chat.
117    pub fn permissions(&self) -> &Permissions {
118        &self.permissions
119    }
120
121    /// Custom administrator title.
122    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    /// Identifier of the person that kicked the participant from the chat.
133    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    /// Restrictions this administrator has in the chat.
142    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}