1use layer_tl_types as tl;
28
29#[derive(Debug, Clone)]
33pub struct User {
34 pub raw: tl::enums::User,
35}
36
37impl User {
38 pub fn from_raw(raw: tl::enums::User) -> Option<Self> {
40 match &raw {
41 tl::enums::User::Empty(_) => None,
42 tl::enums::User::User(_) => Some(Self { raw }),
43 }
44 }
45
46 fn inner(&self) -> &tl::types::User {
47 match &self.raw {
48 tl::enums::User::User(u) => u,
49 tl::enums::User::Empty(_) => unreachable!("User::Empty filtered in from_raw"),
50 }
51 }
52
53 pub fn id(&self) -> i64 {
55 self.inner().id
56 }
57
58 pub fn access_hash(&self) -> Option<i64> {
60 self.inner().access_hash
61 }
62
63 pub fn first_name(&self) -> Option<&str> {
65 self.inner().first_name.as_deref()
66 }
67
68 pub fn last_name(&self) -> Option<&str> {
70 self.inner().last_name.as_deref()
71 }
72
73 pub fn username(&self) -> Option<&str> {
75 self.inner().username.as_deref()
76 }
77
78 pub fn phone(&self) -> Option<&str> {
80 self.inner().phone.as_deref()
81 }
82
83 pub fn verified(&self) -> bool {
85 self.inner().verified
86 }
87
88 pub fn bot(&self) -> bool {
90 self.inner().bot
91 }
92
93 pub fn deleted(&self) -> bool {
95 self.inner().deleted
96 }
97
98 pub fn blocked(&self) -> bool {
100 false
101 }
102
103 pub fn premium(&self) -> bool {
105 self.inner().premium
106 }
107
108 pub fn full_name(&self) -> String {
110 match (self.first_name(), self.last_name()) {
111 (Some(f), Some(l)) => format!("{f} {l}"),
112 (Some(f), None) => f.to_string(),
113 (None, Some(l)) => l.to_string(),
114 (None, None) => String::new(),
115 }
116 }
117
118 pub fn usernames(&self) -> Vec<&str> {
120 let mut names = Vec::new();
121 if let Some(u) = self.inner().username.as_deref() {
123 names.push(u);
124 }
125 if let Some(extras) = &self.inner().usernames {
127 for u in extras {
128 let tl::enums::Username::Username(un) = u;
129 if un.active {
130 names.push(un.username.as_str());
131 }
132 }
133 }
134 names
135 }
136
137 pub fn status(&self) -> Option<&tl::enums::UserStatus> {
139 self.inner().status.as_ref()
140 }
141
142 pub fn photo(&self) -> Option<&tl::types::UserProfilePhoto> {
144 match self.inner().photo.as_ref()? {
145 tl::enums::UserProfilePhoto::UserProfilePhoto(p) => Some(p),
146 _ => None,
147 }
148 }
149
150 pub fn is_self(&self) -> bool {
152 self.inner().is_self
153 }
154
155 pub fn contact(&self) -> bool {
157 self.inner().contact
158 }
159
160 pub fn mutual_contact(&self) -> bool {
162 self.inner().mutual_contact
163 }
164
165 pub fn scam(&self) -> bool {
167 self.inner().scam
168 }
169
170 pub fn restricted(&self) -> bool {
172 self.inner().restricted
173 }
174
175 pub fn bot_privacy(&self) -> bool {
177 self.inner().bot_nochats
178 }
179
180 pub fn bot_supports_chats(&self) -> bool {
182 !self.inner().bot_nochats
183 }
184
185 pub fn bot_inline_geo(&self) -> bool {
187 self.inner().bot_inline_geo
188 }
189
190 pub fn support(&self) -> bool {
192 self.inner().support
193 }
194
195 pub fn lang_code(&self) -> Option<&str> {
197 self.inner().lang_code.as_deref()
198 }
199
200 pub fn restriction_reason(&self) -> Vec<&tl::enums::RestrictionReason> {
202 self.inner()
203 .restriction_reason
204 .as_deref()
205 .unwrap_or(&[])
206 .iter()
207 .collect()
208 }
209
210 pub fn bot_inline_placeholder(&self) -> Option<&str> {
212 self.inner().bot_inline_placeholder.as_deref()
213 }
214
215 pub fn as_peer(&self) -> tl::enums::Peer {
217 tl::enums::Peer::User(tl::types::PeerUser { user_id: self.id() })
218 }
219
220 pub fn as_input_peer(&self) -> tl::enums::InputPeer {
222 match self.inner().access_hash {
223 Some(ah) => tl::enums::InputPeer::User(tl::types::InputPeerUser {
224 user_id: self.id(),
225 access_hash: ah,
226 }),
227 None => tl::enums::InputPeer::PeerSelf,
228 }
229 }
230}
231
232impl std::fmt::Display for User {
233 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
234 let name = self.full_name();
235 if let Some(uname) = self.username() {
236 write!(f, "{name} (@{uname})")
237 } else {
238 write!(f, "{name} [{}]", self.id())
239 }
240 }
241}
242
243#[derive(Debug, Clone)]
247pub struct Group {
248 pub raw: tl::types::Chat,
249}
250
251impl Group {
252 pub fn from_raw(raw: tl::enums::Chat) -> Option<Self> {
255 match raw {
256 tl::enums::Chat::Chat(c) => Some(Self { raw: c }),
257 tl::enums::Chat::Empty(_)
258 | tl::enums::Chat::Forbidden(_)
259 | tl::enums::Chat::Channel(_)
260 | tl::enums::Chat::ChannelForbidden(_) => None,
261 }
262 }
263
264 pub fn id(&self) -> i64 {
266 self.raw.id
267 }
268
269 pub fn title(&self) -> &str {
271 &self.raw.title
272 }
273
274 pub fn participants_count(&self) -> i32 {
276 self.raw.participants_count
277 }
278
279 pub fn creator(&self) -> bool {
281 self.raw.creator
282 }
283
284 pub fn migrated_to(&self) -> Option<&tl::enums::InputChannel> {
286 self.raw.migrated_to.as_ref()
287 }
288
289 pub fn as_peer(&self) -> tl::enums::Peer {
291 tl::enums::Peer::Chat(tl::types::PeerChat { chat_id: self.id() })
292 }
293
294 pub fn as_input_peer(&self) -> tl::enums::InputPeer {
296 tl::enums::InputPeer::Chat(tl::types::InputPeerChat { chat_id: self.id() })
297 }
298}
299
300impl std::fmt::Display for Group {
301 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
302 write!(f, "{} [group {}]", self.title(), self.id())
303 }
304}
305
306#[derive(Debug, Clone, Copy, PartialEq, Eq)]
310pub enum ChannelKind {
311 Broadcast,
313 Megagroup,
315 Gigagroup,
317}
318
319#[derive(Debug, Clone)]
321pub struct Channel {
322 pub raw: tl::types::Channel,
323}
324
325impl Channel {
326 pub fn from_raw(raw: tl::enums::Chat) -> Option<Self> {
328 match raw {
329 tl::enums::Chat::Channel(c) => Some(Self { raw: c }),
330 _ => None,
331 }
332 }
333
334 pub fn id(&self) -> i64 {
336 self.raw.id
337 }
338
339 pub fn access_hash(&self) -> Option<i64> {
341 self.raw.access_hash
342 }
343
344 pub fn title(&self) -> &str {
346 &self.raw.title
347 }
348
349 pub fn username(&self) -> Option<&str> {
351 self.raw.username.as_deref()
352 }
353
354 pub fn megagroup(&self) -> bool {
356 self.raw.megagroup
357 }
358
359 pub fn broadcast(&self) -> bool {
361 self.raw.broadcast
362 }
363
364 pub fn verified(&self) -> bool {
366 self.raw.verified
367 }
368
369 pub fn restricted(&self) -> bool {
371 self.raw.restricted
372 }
373
374 pub fn signatures(&self) -> bool {
376 self.raw.signatures
377 }
378
379 pub fn participants_count(&self) -> Option<i32> {
381 self.raw.participants_count
382 }
383
384 pub fn kind(&self) -> ChannelKind {
389 if self.raw.megagroup {
390 ChannelKind::Megagroup
391 } else if self.raw.gigagroup {
392 ChannelKind::Gigagroup
393 } else {
394 ChannelKind::Broadcast
395 }
396 }
397
398 pub fn usernames(&self) -> Vec<&str> {
400 let mut names = Vec::new();
401 if let Some(u) = self.raw.username.as_deref() {
402 names.push(u);
403 }
404 if let Some(extras) = &self.raw.usernames {
405 for u in extras {
406 let tl::enums::Username::Username(un) = u;
407 if un.active {
408 names.push(un.username.as_str());
409 }
410 }
411 }
412 names
413 }
414
415 pub fn photo(&self) -> Option<&tl::types::ChatPhoto> {
417 match &self.raw.photo {
418 tl::enums::ChatPhoto::ChatPhoto(p) => Some(p),
419 _ => None,
420 }
421 }
422
423 pub fn admin_rights(&self) -> Option<&tl::types::ChatAdminRights> {
425 match self.raw.admin_rights.as_ref()? {
426 tl::enums::ChatAdminRights::ChatAdminRights(r) => Some(r),
427 }
428 }
429
430 pub fn restriction_reason(&self) -> Vec<&tl::enums::RestrictionReason> {
432 self.raw
433 .restriction_reason
434 .as_deref()
435 .unwrap_or(&[])
436 .iter()
437 .collect()
438 }
439
440 pub fn as_peer(&self) -> tl::enums::Peer {
442 tl::enums::Peer::Channel(tl::types::PeerChannel {
443 channel_id: self.id(),
444 })
445 }
446
447 pub fn as_input_peer(&self) -> tl::enums::InputPeer {
449 match self.raw.access_hash {
450 Some(ah) => tl::enums::InputPeer::Channel(tl::types::InputPeerChannel {
451 channel_id: self.id(),
452 access_hash: ah,
453 }),
454 None => tl::enums::InputPeer::Empty,
455 }
456 }
457
458 pub fn as_input_channel(&self) -> tl::enums::InputChannel {
460 match self.raw.access_hash {
461 Some(ah) => tl::enums::InputChannel::InputChannel(tl::types::InputChannel {
462 channel_id: self.id(),
463 access_hash: ah,
464 }),
465 None => tl::enums::InputChannel::Empty,
466 }
467 }
468}
469
470impl std::fmt::Display for Channel {
471 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
472 if let Some(uname) = self.username() {
473 write!(f, "{} (@{uname})", self.title())
474 } else {
475 write!(f, "{} [channel {}]", self.title(), self.id())
476 }
477 }
478}
479
480#[derive(Debug, Clone)]
484pub enum Chat {
485 Group(Group),
486 Channel(Box<Channel>),
487}
488
489impl Chat {
490 pub fn from_raw(raw: tl::enums::Chat) -> Option<Self> {
492 match &raw {
493 tl::enums::Chat::Chat(_) => Group::from_raw(raw).map(Chat::Group),
494 tl::enums::Chat::Channel(_) => {
495 Channel::from_raw(raw).map(|c| Chat::Channel(Box::new(c)))
496 }
497 _ => None,
498 }
499 }
500
501 pub fn id(&self) -> i64 {
503 match self {
504 Chat::Group(g) => g.id(),
505 Chat::Channel(c) => c.id(),
506 }
507 }
508
509 pub fn title(&self) -> &str {
511 match self {
512 Chat::Group(g) => g.title(),
513 Chat::Channel(c) => c.title(),
514 }
515 }
516
517 pub fn as_peer(&self) -> tl::enums::Peer {
519 match self {
520 Chat::Group(g) => g.as_peer(),
521 Chat::Channel(c) => c.as_peer(),
522 }
523 }
524
525 pub fn as_input_peer(&self) -> tl::enums::InputPeer {
527 match self {
528 Chat::Group(g) => g.as_input_peer(),
529 Chat::Channel(c) => c.as_input_peer(),
530 }
531 }
532}