1use layer_tl_types as tl;
10
11#[derive(Debug, Clone)]
15pub struct User {
16 pub raw: tl::enums::User,
17}
18
19impl User {
20 pub fn from_raw(raw: tl::enums::User) -> Option<Self> {
22 match &raw {
23 tl::enums::User::Empty(_) => None,
24 tl::enums::User::User(_) => Some(Self { raw }),
25 }
26 }
27
28 fn inner(&self) -> &tl::types::User {
29 match &self.raw {
30 tl::enums::User::User(u) => u,
31 tl::enums::User::Empty(_) => unreachable!("User::Empty filtered in from_raw"),
32 }
33 }
34
35 pub fn id(&self) -> i64 {
37 self.inner().id
38 }
39
40 pub fn access_hash(&self) -> Option<i64> {
42 self.inner().access_hash
43 }
44
45 pub fn first_name(&self) -> Option<&str> {
47 self.inner().first_name.as_deref()
48 }
49
50 pub fn last_name(&self) -> Option<&str> {
52 self.inner().last_name.as_deref()
53 }
54
55 pub fn username(&self) -> Option<&str> {
57 self.inner().username.as_deref()
58 }
59
60 pub fn phone(&self) -> Option<&str> {
62 self.inner().phone.as_deref()
63 }
64
65 pub fn verified(&self) -> bool {
67 self.inner().verified
68 }
69
70 pub fn bot(&self) -> bool {
72 self.inner().bot
73 }
74
75 pub fn deleted(&self) -> bool {
77 self.inner().deleted
78 }
79
80 pub fn blocked(&self) -> bool {
82 false
83 }
84
85 pub fn premium(&self) -> bool {
87 self.inner().premium
88 }
89
90 pub fn full_name(&self) -> String {
92 match (self.first_name(), self.last_name()) {
93 (Some(f), Some(l)) => format!("{f} {l}"),
94 (Some(f), None) => f.to_string(),
95 (None, Some(l)) => l.to_string(),
96 (None, None) => String::new(),
97 }
98 }
99
100 pub fn usernames(&self) -> Vec<&str> {
102 let mut names = Vec::new();
103 if let Some(u) = self.inner().username.as_deref() {
105 names.push(u);
106 }
107 if let Some(extras) = &self.inner().usernames {
109 for u in extras {
110 let tl::enums::Username::Username(un) = u;
111 if un.active {
112 names.push(un.username.as_str());
113 }
114 }
115 }
116 names
117 }
118
119 pub fn status(&self) -> Option<&tl::enums::UserStatus> {
121 self.inner().status.as_ref()
122 }
123
124 pub fn photo(&self) -> Option<&tl::types::UserProfilePhoto> {
126 match self.inner().photo.as_ref()? {
127 tl::enums::UserProfilePhoto::UserProfilePhoto(p) => Some(p),
128 _ => None,
129 }
130 }
131
132 pub fn is_self(&self) -> bool {
134 self.inner().is_self
135 }
136
137 pub fn contact(&self) -> bool {
139 self.inner().contact
140 }
141
142 pub fn mutual_contact(&self) -> bool {
144 self.inner().mutual_contact
145 }
146
147 pub fn scam(&self) -> bool {
149 self.inner().scam
150 }
151
152 pub fn restricted(&self) -> bool {
154 self.inner().restricted
155 }
156
157 pub fn bot_privacy(&self) -> bool {
159 self.inner().bot_nochats
160 }
161
162 pub fn bot_supports_chats(&self) -> bool {
164 !self.inner().bot_nochats
165 }
166
167 pub fn bot_inline_geo(&self) -> bool {
169 self.inner().bot_inline_geo
170 }
171
172 pub fn support(&self) -> bool {
174 self.inner().support
175 }
176
177 pub fn lang_code(&self) -> Option<&str> {
179 self.inner().lang_code.as_deref()
180 }
181
182 pub fn restriction_reason(&self) -> Vec<&tl::enums::RestrictionReason> {
184 self.inner()
185 .restriction_reason
186 .as_deref()
187 .unwrap_or(&[])
188 .iter()
189 .collect()
190 }
191
192 pub fn bot_inline_placeholder(&self) -> Option<&str> {
194 self.inner().bot_inline_placeholder.as_deref()
195 }
196
197 pub fn as_peer(&self) -> tl::enums::Peer {
199 tl::enums::Peer::User(tl::types::PeerUser { user_id: self.id() })
200 }
201
202 pub fn as_input_peer(&self) -> tl::enums::InputPeer {
204 match self.inner().access_hash {
205 Some(ah) => tl::enums::InputPeer::User(tl::types::InputPeerUser {
206 user_id: self.id(),
207 access_hash: ah,
208 }),
209 None => tl::enums::InputPeer::PeerSelf,
210 }
211 }
212}
213
214impl std::fmt::Display for User {
215 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
216 let name = self.full_name();
217 if let Some(uname) = self.username() {
218 write!(f, "{name} (@{uname})")
219 } else {
220 write!(f, "{name} [{}]", self.id())
221 }
222 }
223}
224
225#[derive(Debug, Clone)]
229pub struct Group {
230 pub raw: tl::types::Chat,
231}
232
233impl Group {
234 pub fn from_raw(raw: tl::enums::Chat) -> Option<Self> {
237 match raw {
238 tl::enums::Chat::Chat(c) => Some(Self { raw: c }),
239 tl::enums::Chat::Empty(_)
240 | tl::enums::Chat::Forbidden(_)
241 | tl::enums::Chat::Channel(_)
242 | tl::enums::Chat::ChannelForbidden(_) => None,
243 }
244 }
245
246 pub fn id(&self) -> i64 {
248 self.raw.id
249 }
250
251 pub fn title(&self) -> &str {
253 &self.raw.title
254 }
255
256 pub fn participants_count(&self) -> i32 {
258 self.raw.participants_count
259 }
260
261 pub fn creator(&self) -> bool {
263 self.raw.creator
264 }
265
266 pub fn migrated_to(&self) -> Option<&tl::enums::InputChannel> {
268 self.raw.migrated_to.as_ref()
269 }
270
271 pub fn as_peer(&self) -> tl::enums::Peer {
273 tl::enums::Peer::Chat(tl::types::PeerChat { chat_id: self.id() })
274 }
275
276 pub fn as_input_peer(&self) -> tl::enums::InputPeer {
278 tl::enums::InputPeer::Chat(tl::types::InputPeerChat { chat_id: self.id() })
279 }
280}
281
282impl std::fmt::Display for Group {
283 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
284 write!(f, "{} [group {}]", self.title(), self.id())
285 }
286}
287
288#[derive(Debug, Clone, Copy, PartialEq, Eq)]
292pub enum ChannelKind {
293 Broadcast,
295 Megagroup,
297 Gigagroup,
299}
300
301#[derive(Debug, Clone)]
303pub struct Channel {
304 pub raw: tl::types::Channel,
305}
306
307impl Channel {
308 pub fn from_raw(raw: tl::enums::Chat) -> Option<Self> {
310 match raw {
311 tl::enums::Chat::Channel(c) => Some(Self { raw: c }),
312 _ => None,
313 }
314 }
315
316 pub fn id(&self) -> i64 {
318 self.raw.id
319 }
320
321 pub fn access_hash(&self) -> Option<i64> {
323 self.raw.access_hash
324 }
325
326 pub fn title(&self) -> &str {
328 &self.raw.title
329 }
330
331 pub fn username(&self) -> Option<&str> {
333 self.raw.username.as_deref()
334 }
335
336 pub fn megagroup(&self) -> bool {
338 self.raw.megagroup
339 }
340
341 pub fn broadcast(&self) -> bool {
343 self.raw.broadcast
344 }
345
346 pub fn verified(&self) -> bool {
348 self.raw.verified
349 }
350
351 pub fn restricted(&self) -> bool {
353 self.raw.restricted
354 }
355
356 pub fn signatures(&self) -> bool {
358 self.raw.signatures
359 }
360
361 pub fn participants_count(&self) -> Option<i32> {
363 self.raw.participants_count
364 }
365
366 pub fn kind(&self) -> ChannelKind {
371 if self.raw.megagroup {
372 ChannelKind::Megagroup
373 } else if self.raw.gigagroup {
374 ChannelKind::Gigagroup
375 } else {
376 ChannelKind::Broadcast
377 }
378 }
379
380 pub fn usernames(&self) -> Vec<&str> {
382 let mut names = Vec::new();
383 if let Some(u) = self.raw.username.as_deref() {
384 names.push(u);
385 }
386 if let Some(extras) = &self.raw.usernames {
387 for u in extras {
388 let tl::enums::Username::Username(un) = u;
389 if un.active {
390 names.push(un.username.as_str());
391 }
392 }
393 }
394 names
395 }
396
397 pub fn photo(&self) -> Option<&tl::types::ChatPhoto> {
399 match &self.raw.photo {
400 tl::enums::ChatPhoto::ChatPhoto(p) => Some(p),
401 _ => None,
402 }
403 }
404
405 pub fn admin_rights(&self) -> Option<&tl::types::ChatAdminRights> {
407 match self.raw.admin_rights.as_ref()? {
408 tl::enums::ChatAdminRights::ChatAdminRights(r) => Some(r),
409 }
410 }
411
412 pub fn restriction_reason(&self) -> Vec<&tl::enums::RestrictionReason> {
414 self.raw
415 .restriction_reason
416 .as_deref()
417 .unwrap_or(&[])
418 .iter()
419 .collect()
420 }
421
422 pub fn as_peer(&self) -> tl::enums::Peer {
424 tl::enums::Peer::Channel(tl::types::PeerChannel {
425 channel_id: self.id(),
426 })
427 }
428
429 pub fn as_input_peer(&self) -> tl::enums::InputPeer {
431 match self.raw.access_hash {
432 Some(ah) => tl::enums::InputPeer::Channel(tl::types::InputPeerChannel {
433 channel_id: self.id(),
434 access_hash: ah,
435 }),
436 None => tl::enums::InputPeer::Empty,
437 }
438 }
439
440 pub fn as_input_channel(&self) -> tl::enums::InputChannel {
442 match self.raw.access_hash {
443 Some(ah) => tl::enums::InputChannel::InputChannel(tl::types::InputChannel {
444 channel_id: self.id(),
445 access_hash: ah,
446 }),
447 None => tl::enums::InputChannel::Empty,
448 }
449 }
450}
451
452impl std::fmt::Display for Channel {
453 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
454 if let Some(uname) = self.username() {
455 write!(f, "{} (@{uname})", self.title())
456 } else {
457 write!(f, "{} [channel {}]", self.title(), self.id())
458 }
459 }
460}
461
462#[derive(Debug, Clone)]
466pub enum Chat {
467 Group(Group),
468 Channel(Box<Channel>),
469}
470
471impl Chat {
472 pub fn from_raw(raw: tl::enums::Chat) -> Option<Self> {
474 match &raw {
475 tl::enums::Chat::Chat(_) => Group::from_raw(raw).map(Chat::Group),
476 tl::enums::Chat::Channel(_) => {
477 Channel::from_raw(raw).map(|c| Chat::Channel(Box::new(c)))
478 }
479 _ => None,
480 }
481 }
482
483 pub fn id(&self) -> i64 {
485 match self {
486 Chat::Group(g) => g.id(),
487 Chat::Channel(c) => c.id(),
488 }
489 }
490
491 pub fn title(&self) -> &str {
493 match self {
494 Chat::Group(g) => g.title(),
495 Chat::Channel(c) => c.title(),
496 }
497 }
498
499 pub fn as_peer(&self) -> tl::enums::Peer {
501 match self {
502 Chat::Group(g) => g.as_peer(),
503 Chat::Channel(c) => c.as_peer(),
504 }
505 }
506
507 pub fn as_input_peer(&self) -> tl::enums::InputPeer {
509 match self {
510 Chat::Group(g) => g.as_input_peer(),
511 Chat::Channel(c) => c.as_input_peer(),
512 }
513 }
514}