use layer_tl_types as tl;
#[derive(Debug, Clone)]
pub struct User {
pub raw: tl::enums::User,
}
impl User {
pub fn from_raw(raw: tl::enums::User) -> Option<Self> {
match &raw {
tl::enums::User::Empty(_) => None,
tl::enums::User::User(_) => Some(Self { raw }),
}
}
fn inner(&self) -> &tl::types::User {
match &self.raw {
tl::enums::User::User(u) => u,
tl::enums::User::Empty(_) => unreachable!("User::Empty filtered in from_raw"),
}
}
pub fn id(&self) -> i64 {
self.inner().id
}
pub fn access_hash(&self) -> Option<i64> {
self.inner().access_hash
}
pub fn first_name(&self) -> Option<&str> {
self.inner().first_name.as_deref()
}
pub fn last_name(&self) -> Option<&str> {
self.inner().last_name.as_deref()
}
pub fn username(&self) -> Option<&str> {
self.inner().username.as_deref()
}
pub fn phone(&self) -> Option<&str> {
self.inner().phone.as_deref()
}
pub fn verified(&self) -> bool {
self.inner().verified
}
pub fn bot(&self) -> bool {
self.inner().bot
}
pub fn deleted(&self) -> bool {
self.inner().deleted
}
pub fn blocked(&self) -> bool {
false
}
pub fn premium(&self) -> bool {
self.inner().premium
}
pub fn full_name(&self) -> String {
match (self.first_name(), self.last_name()) {
(Some(f), Some(l)) => format!("{f} {l}"),
(Some(f), None) => f.to_string(),
(None, Some(l)) => l.to_string(),
(None, None) => String::new(),
}
}
pub fn usernames(&self) -> Vec<&str> {
let mut names = Vec::new();
if let Some(u) = self.inner().username.as_deref() {
names.push(u);
}
if let Some(extras) = &self.inner().usernames {
for u in extras {
let tl::enums::Username::Username(un) = u;
if un.active {
names.push(un.username.as_str());
}
}
}
names
}
pub fn status(&self) -> Option<&tl::enums::UserStatus> {
self.inner().status.as_ref()
}
pub fn photo(&self) -> Option<&tl::types::UserProfilePhoto> {
match self.inner().photo.as_ref()? {
tl::enums::UserProfilePhoto::UserProfilePhoto(p) => Some(p),
_ => None,
}
}
pub fn is_self(&self) -> bool {
self.inner().is_self
}
pub fn contact(&self) -> bool {
self.inner().contact
}
pub fn mutual_contact(&self) -> bool {
self.inner().mutual_contact
}
pub fn scam(&self) -> bool {
self.inner().scam
}
pub fn restricted(&self) -> bool {
self.inner().restricted
}
pub fn bot_privacy(&self) -> bool {
self.inner().bot_nochats
}
pub fn bot_supports_chats(&self) -> bool {
!self.inner().bot_nochats
}
pub fn bot_inline_geo(&self) -> bool {
self.inner().bot_inline_geo
}
pub fn support(&self) -> bool {
self.inner().support
}
pub fn lang_code(&self) -> Option<&str> {
self.inner().lang_code.as_deref()
}
pub fn restriction_reason(&self) -> Vec<&tl::enums::RestrictionReason> {
self.inner()
.restriction_reason
.as_deref()
.unwrap_or(&[])
.iter()
.collect()
}
pub fn bot_inline_placeholder(&self) -> Option<&str> {
self.inner().bot_inline_placeholder.as_deref()
}
pub fn as_peer(&self) -> tl::enums::Peer {
tl::enums::Peer::User(tl::types::PeerUser { user_id: self.id() })
}
pub fn as_input_peer(&self) -> tl::enums::InputPeer {
match self.inner().access_hash {
Some(ah) => tl::enums::InputPeer::User(tl::types::InputPeerUser {
user_id: self.id(),
access_hash: ah,
}),
None => tl::enums::InputPeer::PeerSelf,
}
}
}
impl std::fmt::Display for User {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let name = self.full_name();
if let Some(uname) = self.username() {
write!(f, "{name} (@{uname})")
} else {
write!(f, "{name} [{}]", self.id())
}
}
}
#[derive(Debug, Clone)]
pub struct Group {
pub raw: tl::types::Chat,
}
impl Group {
pub fn from_raw(raw: tl::enums::Chat) -> Option<Self> {
match raw {
tl::enums::Chat::Chat(c) => Some(Self { raw: c }),
tl::enums::Chat::Empty(_)
| tl::enums::Chat::Forbidden(_)
| tl::enums::Chat::Channel(_)
| tl::enums::Chat::ChannelForbidden(_) => None,
}
}
pub fn id(&self) -> i64 {
self.raw.id
}
pub fn title(&self) -> &str {
&self.raw.title
}
pub fn participants_count(&self) -> i32 {
self.raw.participants_count
}
pub fn creator(&self) -> bool {
self.raw.creator
}
pub fn migrated_to(&self) -> Option<&tl::enums::InputChannel> {
self.raw.migrated_to.as_ref()
}
pub fn as_peer(&self) -> tl::enums::Peer {
tl::enums::Peer::Chat(tl::types::PeerChat { chat_id: self.id() })
}
pub fn as_input_peer(&self) -> tl::enums::InputPeer {
tl::enums::InputPeer::Chat(tl::types::InputPeerChat { chat_id: self.id() })
}
}
impl std::fmt::Display for Group {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} [group {}]", self.title(), self.id())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ChannelKind {
Broadcast,
Megagroup,
Gigagroup,
}
#[derive(Debug, Clone)]
pub struct Channel {
pub raw: tl::types::Channel,
}
impl Channel {
pub fn from_raw(raw: tl::enums::Chat) -> Option<Self> {
match raw {
tl::enums::Chat::Channel(c) => Some(Self { raw: c }),
_ => None,
}
}
pub fn id(&self) -> i64 {
self.raw.id
}
pub fn access_hash(&self) -> Option<i64> {
self.raw.access_hash
}
pub fn title(&self) -> &str {
&self.raw.title
}
pub fn username(&self) -> Option<&str> {
self.raw.username.as_deref()
}
pub fn megagroup(&self) -> bool {
self.raw.megagroup
}
pub fn broadcast(&self) -> bool {
self.raw.broadcast
}
pub fn verified(&self) -> bool {
self.raw.verified
}
pub fn restricted(&self) -> bool {
self.raw.restricted
}
pub fn signatures(&self) -> bool {
self.raw.signatures
}
pub fn participants_count(&self) -> Option<i32> {
self.raw.participants_count
}
pub fn kind(&self) -> ChannelKind {
if self.raw.megagroup {
ChannelKind::Megagroup
} else if self.raw.gigagroup {
ChannelKind::Gigagroup
} else {
ChannelKind::Broadcast
}
}
pub fn usernames(&self) -> Vec<&str> {
let mut names = Vec::new();
if let Some(u) = self.raw.username.as_deref() {
names.push(u);
}
if let Some(extras) = &self.raw.usernames {
for u in extras {
let tl::enums::Username::Username(un) = u;
if un.active {
names.push(un.username.as_str());
}
}
}
names
}
pub fn photo(&self) -> Option<&tl::types::ChatPhoto> {
match &self.raw.photo {
tl::enums::ChatPhoto::ChatPhoto(p) => Some(p),
_ => None,
}
}
pub fn admin_rights(&self) -> Option<&tl::types::ChatAdminRights> {
match self.raw.admin_rights.as_ref()? {
tl::enums::ChatAdminRights::ChatAdminRights(r) => Some(r),
}
}
pub fn restriction_reason(&self) -> Vec<&tl::enums::RestrictionReason> {
self.raw
.restriction_reason
.as_deref()
.unwrap_or(&[])
.iter()
.collect()
}
pub fn as_peer(&self) -> tl::enums::Peer {
tl::enums::Peer::Channel(tl::types::PeerChannel {
channel_id: self.id(),
})
}
pub fn as_input_peer(&self) -> tl::enums::InputPeer {
match self.raw.access_hash {
Some(ah) => tl::enums::InputPeer::Channel(tl::types::InputPeerChannel {
channel_id: self.id(),
access_hash: ah,
}),
None => tl::enums::InputPeer::Empty,
}
}
pub fn as_input_channel(&self) -> tl::enums::InputChannel {
match self.raw.access_hash {
Some(ah) => tl::enums::InputChannel::InputChannel(tl::types::InputChannel {
channel_id: self.id(),
access_hash: ah,
}),
None => tl::enums::InputChannel::Empty,
}
}
}
impl std::fmt::Display for Channel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(uname) = self.username() {
write!(f, "{} (@{uname})", self.title())
} else {
write!(f, "{} [channel {}]", self.title(), self.id())
}
}
}
#[derive(Debug, Clone)]
pub enum Chat {
Group(Group),
Channel(Box<Channel>),
}
impl Chat {
pub fn from_raw(raw: tl::enums::Chat) -> Option<Self> {
match &raw {
tl::enums::Chat::Chat(_) => Group::from_raw(raw).map(Chat::Group),
tl::enums::Chat::Channel(_) => {
Channel::from_raw(raw).map(|c| Chat::Channel(Box::new(c)))
}
_ => None,
}
}
pub fn id(&self) -> i64 {
match self {
Chat::Group(g) => g.id(),
Chat::Channel(c) => c.id(),
}
}
pub fn title(&self) -> &str {
match self {
Chat::Group(g) => g.title(),
Chat::Channel(c) => c.title(),
}
}
pub fn as_peer(&self) -> tl::enums::Peer {
match self {
Chat::Group(g) => g.as_peer(),
Chat::Channel(c) => c.as_peer(),
}
}
pub fn as_input_peer(&self) -> tl::enums::InputPeer {
match self {
Chat::Group(g) => g.as_input_peer(),
Chat::Channel(c) => c.as_input_peer(),
}
}
}