grammers_client/types/peer/mod.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.
8mod channel;
9mod group;
10mod user;
11
12use grammers_session::defs::{PeerAuth, PeerId, PeerRef};
13use grammers_tl_types as tl;
14
15pub use channel::Channel;
16pub use group::Group;
17pub use user::{Platform, RestrictionReason, User};
18
19/// A peer.
20///
21/// Peers represent places where you can share messages with others.
22///
23/// * Private conversations with other people are treated as the peer of the user itself.
24/// * Conversations in a group, whether it's private or public, are simply known as groups.
25/// * Conversations where only administrators broadcast messages are known as channels.
26#[derive(Clone, Debug)]
27pub enum Peer {
28 /// A [`User`].
29 User(User),
30
31 /// A [`Group`] chat.
32 Group(Group),
33
34 /// A broadcast [`Channel`].
35 Channel(Channel),
36}
37
38impl Peer {
39 pub(crate) fn from_user(user: tl::enums::User) -> Self {
40 Self::User(User::from_raw(user))
41 }
42
43 pub fn from_raw(chat: tl::enums::Chat) -> Self {
44 use tl::enums::Chat as C;
45
46 match chat {
47 C::Empty(_) | C::Chat(_) | C::Forbidden(_) => Self::Group(Group::from_raw(chat)),
48 C::Channel(ref channel) => {
49 if channel.broadcast {
50 Self::Channel(Channel::from_raw(chat))
51 } else {
52 Self::Group(Group::from_raw(chat))
53 }
54 }
55 C::ChannelForbidden(ref channel) => {
56 if channel.broadcast {
57 Self::Channel(Channel::from_raw(chat))
58 } else {
59 Self::Group(Group::from_raw(chat))
60 }
61 }
62 }
63 }
64
65 /// Return the unique identifier for this peer.
66 ///
67 /// Every account will see the same identifier for the same peer.
68 ///
69 /// This identifier will never change. However, small group chats may be migrated to
70 /// megagroups. If this happens, both the old small group chat and the new megagroup
71 /// exist as separate chats with different identifiers, but they are linked with a
72 /// property.
73 pub fn id(&self) -> PeerId {
74 match self {
75 Self::User(user) => PeerId::user(user.bare_id()),
76 Self::Group(group) => group.id(),
77 Self::Channel(channel) => PeerId::channel(channel.bare_id()),
78 }
79 }
80
81 pub(crate) fn auth(&self) -> PeerAuth {
82 match self {
83 Self::User(user) => user.auth(),
84 Self::Group(group) => group.auth(),
85 Self::Channel(channel) => channel.auth(),
86 }
87 }
88
89 /// Return the name of this peer.
90 ///
91 /// For private conversations (users), this is their first name. For groups and channels,
92 /// this is their title.
93 ///
94 /// The name will be `None` if the peer is inaccessible or if the account was deleted. It may
95 /// also be `None` if you received it previously.
96 pub fn name(&self) -> Option<&str> {
97 match self {
98 Self::User(user) => user.first_name(),
99 Self::Group(group) => group.title(),
100 Self::Channel(channel) => Some(channel.title()),
101 }
102 }
103
104 /// Return the public @username of this peer, if any.
105 ///
106 /// The returned username does not contain the "@" prefix.
107 ///
108 /// Outside of the application, people may link to this user with one of Telegram's URLs, such
109 /// as https://t.me/username.
110 pub fn username(&self) -> Option<&str> {
111 match self {
112 Self::User(user) => user.username(),
113 Self::Group(group) => group.username(),
114 Self::Channel(channel) => channel.username(),
115 }
116 }
117
118 /// Return collectible usernames of this peer, if any.
119 ///
120 /// The returned usernames do not contain the "@" prefix.
121 ///
122 /// Outside of the application, people may link to this user with one of its username, such
123 /// as https://t.me/username.
124 pub fn usernames(&self) -> Vec<&str> {
125 match self {
126 Self::User(user) => user.usernames(),
127 Self::Group(group) => group.usernames(),
128 Self::Channel(channel) => channel.usernames(),
129 }
130 }
131
132 // Return the profile picture or chat photo of this peer, if any.
133 pub fn photo(&self, big: bool) -> Option<crate::types::ChatPhoto> {
134 let peer = PeerRef::from(self).into();
135 match self {
136 Self::User(user) => user.photo().map(|x| crate::types::ChatPhoto {
137 raw: tl::enums::InputFileLocation::InputPeerPhotoFileLocation(
138 tl::types::InputPeerPhotoFileLocation {
139 big,
140 peer,
141 photo_id: x.photo_id,
142 },
143 ),
144 }),
145 Self::Group(group) => group.photo().map(|x| crate::types::ChatPhoto {
146 raw: tl::enums::InputFileLocation::InputPeerPhotoFileLocation(
147 tl::types::InputPeerPhotoFileLocation {
148 big,
149 peer,
150 photo_id: x.photo_id,
151 },
152 ),
153 }),
154 Self::Channel(channel) => channel.photo().map(|x| crate::types::ChatPhoto {
155 raw: tl::enums::InputFileLocation::InputPeerPhotoFileLocation(
156 tl::types::InputPeerPhotoFileLocation {
157 big,
158 peer,
159 photo_id: x.photo_id,
160 },
161 ),
162 }),
163 }
164 }
165}
166
167impl From<Peer> for PeerRef {
168 fn from(peer: Peer) -> Self {
169 PeerRef {
170 id: peer.id(),
171 auth: peer.auth(),
172 }
173 }
174}
175
176impl From<&Peer> for PeerRef {
177 fn from(peer: &Peer) -> Self {
178 PeerRef {
179 id: peer.id(),
180 auth: peer.auth(),
181 }
182 }
183}