use serde::de::{Deserialize, Deserializer, Error};
use crate::types::*;
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Deserialize)]
pub struct User {
pub id: UserId,
pub first_name: String,
pub last_name: Option<String>,
pub username: Option<String>,
pub is_bot: bool,
pub language_code: Option<String>,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Deserialize)]
pub struct Group {
pub id: GroupId,
pub title: String,
pub all_members_are_administrators: bool,
pub invite_link: Option<String>,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Deserialize)]
pub struct Supergroup {
pub id: SupergroupId,
pub title: String,
pub username: Option<String>,
pub invite_link: Option<String>,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Deserialize)]
pub struct Channel {
pub id: ChannelId,
pub title: String,
pub username: Option<String>,
pub invite_link: Option<String>,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
pub enum MessageChat {
Private(User),
Group(Group),
Supergroup(Supergroup),
#[doc(hidden)]
Unknown(RawChat),
}
impl MessageChat {
pub fn id(&self) -> ChatId {
match *self {
MessageChat::Private(ref x) => x.id.into(),
MessageChat::Group(ref x) => x.id.into(),
MessageChat::Supergroup(ref x) => x.id.into(),
MessageChat::Unknown(ref x) => x.id.into(),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
pub enum Chat {
Private(User),
Group(Group),
Supergroup(Supergroup),
Channel(Channel),
#[doc(hidden)]
Unknown(RawChat),
}
impl Chat {
pub fn id(&self) -> ChatId {
match *self {
Chat::Private(ref x) => x.id.into(),
Chat::Group(ref x) => x.id.into(),
Chat::Supergroup(ref x) => x.id.into(),
Chat::Channel(ref x) => x.id.into(),
Chat::Unknown(ref x) => x.id.into(),
}
}
}
impl<'de> Deserialize<'de> for Chat {
fn deserialize<D>(deserializer: D) -> Result<Chat, D::Error>
where
D: Deserializer<'de>,
{
let raw: RawChat = Deserialize::deserialize(deserializer)?;
macro_rules! required_field {
($name:ident) => {{
match raw.$name {
Some(val) => val,
None => return Err(D::Error::missing_field(stringify!($name))),
}
}};
}
Ok(match raw.type_.as_ref() {
"private" => Chat::Private(User {
id: raw.id.into(),
username: raw.username,
first_name: required_field!(first_name),
last_name: raw.last_name,
is_bot: false,
language_code: raw.language_code,
}),
"group" => Chat::Group(Group {
id: raw.id.into(),
title: required_field!(title),
all_members_are_administrators: required_field!(all_members_are_administrators),
invite_link: raw.invite_link,
}),
"supergroup" => Chat::Supergroup(Supergroup {
id: raw.id.into(),
title: required_field!(title),
username: raw.username,
invite_link: raw.invite_link,
}),
"channel" => Chat::Channel(Channel {
id: raw.id.into(),
title: required_field!(title),
username: raw.username,
invite_link: raw.invite_link,
}),
_ => Chat::Unknown(raw),
})
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Deserialize)]
pub struct RawChat {
pub id: Integer,
#[serde(rename = "type")]
pub type_: String,
pub title: Option<String>,
pub username: Option<String>,
pub first_name: Option<String>,
pub last_name: Option<String>,
pub invite_link: Option<String>,
pub language_code: Option<String>,
pub all_members_are_administrators: Option<bool>,
}