Split big enumerations' variants into new types

This commit is contained in:
Temirkhan Myrzamadi 2020-05-08 12:57:50 +06:00
parent 157d571251
commit 65e210fff1
10 changed files with 1507 additions and 1164 deletions

View file

@ -28,54 +28,62 @@ pub struct Chat {
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)] #[serde(untagged)]
pub enum ChatKind { pub enum ChatKind {
NonPrivate { NonPrivate(ChatNonPrivate),
/// A title, for supergroups, channels and group chats. Private(ChatPrivate),
title: Option<String>, }
#[serde(flatten)] #[serde_with_macros::skip_serializing_none]
kind: NonPrivateChatKind, #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ChatNonPrivate {
/// A title, for supergroups, channels and group chats.
pub title: Option<String>,
/// A description, for groups, supergroups and channel chats. Returned #[serde(flatten)]
/// only in [`Bot::get_chat`]. pub kind: NonPrivateChatKind,
///
/// [`Bot::get_chat`]: crate::Bot::get_chat
description: Option<String>,
/// A chat invite link, for groups, supergroups and channel chats. Each /// A description, for groups, supergroups and channel chats. Returned
/// administrator in a chat generates their own invite links, so the /// only in [`Bot::get_chat`].
/// bot must first generate the link using ///
/// [`Bot::export_chat_invite_link`]. Returned only in /// [`Bot::get_chat`]: crate::Bot::get_chat
/// [`Bot::get_chat`]. pub description: Option<String>,
///
/// [`Bot::export_chat_invite_link`]:
/// crate::Bot::export_chat_invite_link
///
/// [`Bot::get_chat`]: crate::Bot::get_chat
invite_link: Option<String>,
/// Pinned message, for groups, supergroups and channels. Returned only /// A chat invite link, for groups, supergroups and channel chats. Each
/// in [`Bot::get_chat`]. /// administrator in a chat generates their own invite links, so the
/// /// bot must first generate the link using
/// [`Bot::get_chat`]: crate::Bot::get_chat /// [`Bot::export_chat_invite_link`]. Returned only in
pinned_message: Option<Box<Message>>, /// [`Bot::get_chat`].
}, ///
Private { /// [`Bot::export_chat_invite_link`]:
/// A dummy field. Used to ensure that the `type` field is equal to /// crate::Bot::export_chat_invite_link
/// `private`. ///
#[serde(rename = "type")] /// [`Bot::get_chat`]: crate::Bot::get_chat
#[serde(deserialize_with = "assert_private_field")] pub invite_link: Option<String>,
type_: (),
/// A username, for private chats, supergroups and channels if /// Pinned message, for groups, supergroups and channels. Returned only
/// available. /// in [`Bot::get_chat`].
username: Option<String>, ///
/// [`Bot::get_chat`]: crate::Bot::get_chat
pub pinned_message: Option<Box<Message>>,
}
/// A first name of the other party in a private chat. #[serde_with_macros::skip_serializing_none]
first_name: Option<String>, #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ChatPrivate {
/// A dummy field. Used to ensure that the `type` field is equal to
/// `private`.
#[serde(rename = "type")]
#[serde(deserialize_with = "assert_private_field")]
pub type_: (),
/// A last name of the other party in a private chat. /// A username, for private chats, supergroups and channels if
last_name: Option<String>, /// available.
}, pub username: Option<String>,
/// A first name of the other party in a private chat.
pub first_name: Option<String>,
/// A last name of the other party in a private chat.
pub last_name: Option<String>,
} }
#[serde_with_macros::skip_serializing_none] #[serde_with_macros::skip_serializing_none]
@ -83,47 +91,58 @@ pub enum ChatKind {
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
#[serde(tag = "type")] #[serde(tag = "type")]
pub enum NonPrivateChatKind { pub enum NonPrivateChatKind {
Channel { Channel(NonPrivateChatChannel),
/// A username, for private chats, supergroups and channels if Group(NonPrivateChatGroup),
/// available. Supergroup(NonPrivateChatSupergroup),
username: Option<String>, }
},
Group {
/// A default chat member permissions, for groups and supergroups.
/// Returned only in [`Bot::get_chat`].
///
/// [`Bot::get_chat`]: crate::Bot::get_chat
permissions: Option<ChatPermissions>,
},
Supergroup {
/// A username, for private chats, supergroups and channels if
/// available.
username: Option<String>,
/// For supergroups, name of group sticker set. Returned only in #[serde_with_macros::skip_serializing_none]
/// [`Bot::get_chat`]. #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
/// pub struct NonPrivateChatChannel {
/// [`Bot::get_chat`]: crate::Bot::get_chat /// A username, for private chats, supergroups and channels if available.
sticker_set_name: Option<String>, pub username: Option<String>,
}
/// `true`, if the bot can change the group sticker set. Returned only #[serde_with_macros::skip_serializing_none]
/// in [`Bot::get_chat`]. #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
/// pub struct NonPrivateChatGroup {
/// [`Bot::get_chat`]: crate::Bot::get_chat /// A default chat member permissions, for groups and supergroups. Returned
can_set_sticker_set: Option<bool>, /// only from [`Bot::get_chat`].
///
/// [`Bot::get_chat`]: crate::Bot::get_chat
pub permissions: Option<ChatPermissions>,
}
/// A default chat member permissions, for groups and supergroups. #[serde_with_macros::skip_serializing_none]
/// Returned only in [`Bot::get_chat`]. #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
/// pub struct NonPrivateChatSupergroup {
/// [`Bot::get_chat`]: crate::Bot::get_chat /// A username, for private chats, supergroups and channels if
permissions: Option<ChatPermissions>, /// available.
pub username: Option<String>,
/// The minimum allowed delay between consecutive messages sent by each /// For supergroups, name of group sticker set. Returned only from
/// unpriviledged user. Returned only in [`Bot::get_chat`]. /// [`Bot::get_chat`].
/// ///
/// [`Bot::get_chat`]: crate::Bot::get_chat /// [`Bot::get_chat`]: crate::Bot::get_chat
slow_mode_delay: Option<i32>, pub sticker_set_name: Option<String>,
},
/// `true`, if the bot can change the group sticker set. Returned only
/// from [`Bot::get_chat`].
///
/// [`Bot::get_chat`]: crate::Bot::get_chat
pub can_set_sticker_set: Option<bool>,
/// A default chat member permissions, for groups and supergroups.
/// Returned only from [`Bot::get_chat`].
///
/// [`Bot::get_chat`]: crate::Bot::get_chat
pub permissions: Option<ChatPermissions>,
/// The minimum allowed delay between consecutive messages sent by each
/// unpriviledged user. Returned only from [`Bot::get_chat`].
///
/// [`Bot::get_chat`]: crate::Bot::get_chat
pub slow_mode_delay: Option<i32>,
} }
struct PrivateChatKindVisitor; struct PrivateChatKindVisitor;
@ -158,38 +177,36 @@ where
impl Chat { impl Chat {
pub fn is_private(&self) -> bool { pub fn is_private(&self) -> bool {
match self.kind { matches!(self.kind, ChatKind::Private(_))
ChatKind::Private { .. } => true,
_ => false,
}
} }
pub fn is_group(&self) -> bool { pub fn is_group(&self) -> bool {
match self.kind { matches!(
ChatKind::NonPrivate { self.kind,
kind: NonPrivateChatKind::Group { .. }, ChatKind::NonPrivate(ChatNonPrivate {
kind: NonPrivateChatKind::Group(_),
.. ..
} => true, })
_ => false, )
}
} }
pub fn is_supergroup(&self) -> bool { pub fn is_supergroup(&self) -> bool {
match self.kind { matches!(
ChatKind::NonPrivate { self.kind,
kind: NonPrivateChatKind::Supergroup { .. }, ChatKind::NonPrivate(ChatNonPrivate {
kind: NonPrivateChatKind::Supergroup(_),
.. ..
} => true, })
_ => false, )
}
} }
pub fn is_channel(&self) -> bool { pub fn is_channel(&self) -> bool {
match self.kind { matches!(
ChatKind::NonPrivate { self.kind,
kind: NonPrivateChatKind::Channel { .. }, ChatKind::NonPrivate(ChatNonPrivate {
kind: NonPrivateChatKind::Channel(_),
.. ..
} => true, })
_ => false, )
}
} }
pub fn is_chat(&self) -> bool { pub fn is_chat(&self) -> bool {
self.is_private() || self.is_group() || self.is_supergroup() self.is_private() || self.is_group() || self.is_supergroup()
} }
@ -205,15 +222,15 @@ mod tests {
fn channel_de() { fn channel_de() {
let expected = Chat { let expected = Chat {
id: -1, id: -1,
kind: ChatKind::NonPrivate { kind: ChatKind::NonPrivate(ChatNonPrivate {
title: None, title: None,
kind: NonPrivateChatKind::Channel { kind: NonPrivateChatKind::Channel(NonPrivateChatChannel {
username: Some("channelname".into()), username: Some("channelname".into()),
}, }),
description: None, description: None,
invite_link: None, invite_link: None,
pinned_message: None, pinned_message: None,
}, }),
photo: None, photo: None,
}; };
let actual = let actual =
@ -227,12 +244,12 @@ mod tests {
assert_eq!( assert_eq!(
Chat { Chat {
id: 0, id: 0,
kind: ChatKind::Private { kind: ChatKind::Private(ChatPrivate {
type_: (), type_: (),
username: Some("username".into()), username: Some("username".into()),
first_name: Some("Anon".into()), first_name: Some("Anon".into()),
last_name: None, last_name: None,
}, }),
photo: None, photo: None,
}, },
from_str( from_str(

View file

@ -19,337 +19,391 @@ pub struct EncryptedPassportElement {
pub kind: EncryptedPassportElementKind, pub kind: EncryptedPassportElementKind,
} }
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
#[allow(clippy::large_enum_variant)]
pub enum EncryptedPassportElementKind { pub enum EncryptedPassportElementKind {
PersonalDetails { PersonalDetails(EncryptedPassportElementPersonalDetails),
/// Base64-encoded encrypted Telegram Passport element data provided Passport(EncryptedPassportElementPassport),
/// by the user, available for `personal_details`, `passport`, DriverLicense(EncryptedPassportElementDriverLicense),
/// `driver_license`, `identity_card`, `internal_passport` and IdentityCard(EncryptedPassportElementIdentityCard),
/// `address` types. Can be decrypted and verified using the InternalPassport(EncryptedPassportElementInternalPassport),
/// accompanying [`EncryptedCredentials`]. Address(EncryptedPassportElementAddress),
/// UtilityBill(EncryptedPassportElementUtilityBill),
/// [`EncryptedCredentials`]: BankStatement(EncryptedPassportElementBankStatement),
/// crate::types::EncryptedCredentials RentalAgreement(EncryptedPassportElementRentalAgreement),
data: String, PassportRegistration(EncryptedPassportElementPassportRegistration),
}, EncryptedPassportElement(EncryptedPassportElementTemporaryRegistration),
Passport { PhoneNumber(EncryptedPassportElementPhoneNumber),
/// Base64-encoded encrypted Telegram Passport element data provided Email(EncryptedPassportElementEmail),
/// by the user, available for `personal_details`, `passport`, }
/// `driver_license`, `identity_card`, `internal_passport` and
/// `address` types. Can be decrypted and verified using the #[serde_with_macros::skip_serializing_none]
/// accompanying [`EncryptedCredentials`]. #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
/// pub struct EncryptedPassportElementPersonalDetails {
/// [`EncryptedCredentials`]: /// Base64-encoded encrypted Telegram Passport element data provided
/// crate::types::EncryptedCredentials /// by the user, available for `personal_details`, `passport`,
data: String, /// `driver_license`, `identity_card`, `internal_passport` and
/// `address` types. Can be decrypted and verified using the
/// Encrypted file with the front side of the document, provided by the /// accompanying [`EncryptedCredentials`].
/// user. Available for `passport`, `driver_license`, `identity_card` ///
/// and `internal_passport`. The file can be decrypted and verified /// [`EncryptedCredentials`]:
/// using the accompanying [`EncryptedCredentials`]. /// crate::types::EncryptedCredentials
/// pub data: String,
/// [`EncryptedCredentials`]: }
/// crate::types::EncryptedCredentials
front_side: PassportFile, #[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
/// Encrypted file with the selfie of the user holding a document, pub struct EncryptedPassportElementPassport {
/// provided by the user; available for `passport`, `driver_license`, /// Base64-encoded encrypted Telegram Passport element data provided
/// `identity_card` and `internal_passport`. The file can be decrypted /// by the user, available for `personal_details`, `passport`,
/// and verified using the accompanying [`EncryptedCredentials`]. /// `driver_license`, `identity_card`, `internal_passport` and
/// /// `address` types. Can be decrypted and verified using the
/// [`EncryptedCredentials`]: /// accompanying [`EncryptedCredentials`].
/// crate::types::EncryptedCredentials ///
selfie: PassportFile, /// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
/// Array of encrypted files with translated versions of documents pub data: String,
/// provided by the user. Available if requested for `passport`,
/// `driver_license`, `identity_card`, `internal_passport`, /// Encrypted file with the front side of the document, provided by the
/// `utility_bill`, `bank_statement`, `rental_agreement`, /// user. Available for `passport`, `driver_license`, `identity_card`
/// `passport_registration` and `temporary_registration` types. Files /// and `internal_passport`. The file can be decrypted and verified
/// can be decrypted and verified using the accompanying /// using the accompanying [`EncryptedCredentials`].
/// [`EncryptedCredentials`]. ///
/// /// [`EncryptedCredentials`]:
/// [`EncryptedCredentials`]: /// crate::types::EncryptedCredentials
/// crate::types::EncryptedCredentials pub front_side: PassportFile,
translation: Option<Vec<PassportFile>>,
}, /// Encrypted file with the selfie of the user holding a document,
DriverLicense { /// provided by the user; available for `passport`, `driver_license`,
/// Base64-encoded encrypted Telegram Passport element data provided /// `identity_card` and `internal_passport`. The file can be decrypted
/// by the user, available for `personal_details`, `passport`, /// and verified using the accompanying [`EncryptedCredentials`].
/// `driver_license`, `identity_card`, `internal_passport` and ///
/// `address` types. Can be decrypted and verified using the /// [`EncryptedCredentials`]:
/// accompanying [`EncryptedCredentials`]. /// crate::types::EncryptedCredentials
/// pub selfie: PassportFile,
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials /// Array of encrypted files with translated versions of documents
data: String, /// provided by the user. Available if requested for `passport`,
/// `driver_license`, `identity_card`, `internal_passport`,
/// Encrypted file with the front side of the document, provided by the /// `utility_bill`, `bank_statement`, `rental_agreement`,
/// user. Available for `passport`, `driver_license`, `identity_card` /// `passport_registration` and `temporary_registration` types. Files
/// and `internal_passport`. The file can be decrypted and verified /// can be decrypted and verified using the accompanying
/// using the accompanying [`EncryptedCredentials`]. /// [`EncryptedCredentials`].
/// ///
/// [`EncryptedCredentials`]: /// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials /// crate::types::EncryptedCredentials
front_side: PassportFile, pub translation: Option<Vec<PassportFile>>,
}
/// Encrypted file with the reverse side of the document, provided by
/// the user. Available for `driver_license` and `identity_card`. The #[serde_with_macros::skip_serializing_none]
/// file can be decrypted and verified using the accompanying #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
/// [`EncryptedCredentials`]. pub struct EncryptedPassportElementDriverLicense {
/// /// Base64-encoded encrypted Telegram Passport element data provided
/// [`EncryptedCredentials`]: /// by the user, available for `personal_details`, `passport`,
/// crate::types::EncryptedCredentials /// `driver_license`, `identity_card`, `internal_passport` and
reverse_side: PassportFile, /// `address` types. Can be decrypted and verified using the
/// accompanying [`EncryptedCredentials`].
/// Encrypted file with the selfie of the user holding a document, ///
/// provided by the user; available for `passport`, `driver_license`, /// [`EncryptedCredentials`]:
/// `identity_card` and `internal_passport`. The file can be decrypted /// crate::types::EncryptedCredentials
/// and verified using the accompanying [`EncryptedCredentials`]. pub data: String,
///
/// [`EncryptedCredentials`]: /// Encrypted file with the front side of the document, provided by the
/// crate::types::EncryptedCredentials /// user. Available for `passport`, `driver_license`, `identity_card`
selfie: PassportFile, /// and `internal_passport`. The file can be decrypted and verified
/// using the accompanying [`EncryptedCredentials`].
/// Array of encrypted files with translated versions of documents ///
/// provided by the user. Available if requested for `passport`, /// [`EncryptedCredentials`]:
/// `driver_license`, `identity_card`, `internal_passport`, /// crate::types::EncryptedCredentials
/// `utility_bill`, `bank_statement`, `rental_agreement`, pub front_side: PassportFile,
/// `passport_registration` and `temporary_registration` types. Files
/// can be decrypted and verified using the accompanying /// Encrypted file with the reverse side of the document, provided by
/// [`EncryptedCredentials`]. /// the user. Available for `driver_license` and `identity_card`. The
/// /// file can be decrypted and verified using the accompanying
/// [`EncryptedCredentials`]: /// [`EncryptedCredentials`].
/// crate::types::EncryptedCredentials ///
translation: Option<Vec<PassportFile>>, /// [`EncryptedCredentials`]:
}, /// crate::types::EncryptedCredentials
IdentityCard { pub reverse_side: PassportFile,
/// Base64-encoded encrypted Telegram Passport element data provided
/// by the user, available for `personal_details`, `passport`, /// Encrypted file with the selfie of the user holding a document,
/// `driver_license`, `identity_card`, `internal_passport` and /// provided by the user; available for `passport`, `driver_license`,
/// `address` types. Can be decrypted and verified using the /// `identity_card` and `internal_passport`. The file can be decrypted
/// accompanying [`EncryptedCredentials`]. /// and verified using the accompanying [`EncryptedCredentials`].
/// ///
/// [`EncryptedCredentials`]: /// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials /// crate::types::EncryptedCredentials
data: String, pub selfie: PassportFile,
/// Encrypted file with the front side of the document, provided by the /// Array of encrypted files with translated versions of documents
/// user. Available for `passport`, `driver_license`, `identity_card` /// provided by the user. Available if requested for `passport`,
/// and `internal_passport`. The file can be decrypted and verified /// `driver_license`, `identity_card`, `internal_passport`,
/// using the accompanying [`EncryptedCredentials`]. /// `utility_bill`, `bank_statement`, `rental_agreement`,
/// /// `passport_registration` and `temporary_registration` types. Files
/// [`EncryptedCredentials`]: /// can be decrypted and verified using the accompanying
/// crate::types::EncryptedCredentials /// [`EncryptedCredentials`].
front_side: PassportFile, ///
/// [`EncryptedCredentials`]:
/// Encrypted file with the reverse side of the document, provided by /// crate::types::EncryptedCredentials
/// the user. Available for `driver_license` and `identity_card`. The pub translation: Option<Vec<PassportFile>>,
/// file can be decrypted and verified using the accompanying }
/// [`EncryptedCredentials`].
/// #[serde_with_macros::skip_serializing_none]
/// [`EncryptedCredentials`]: #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
/// crate::types::EncryptedCredentials pub struct EncryptedPassportElementIdentityCard {
reverse_side: PassportFile, /// Base64-encoded encrypted Telegram Passport element data provided
/// by the user, available for `personal_details`, `passport`,
/// Encrypted file with the selfie of the user holding a document, /// `driver_license`, `identity_card`, `internal_passport` and
/// provided by the user; available for `passport`, `driver_license`, /// `address` types. Can be decrypted and verified using the
/// `identity_card` and `internal_passport`. The file can be decrypted /// accompanying [`EncryptedCredentials`].
/// and verified using the accompanying [`EncryptedCredentials`]. ///
/// /// [`EncryptedCredentials`]:
/// [`EncryptedCredentials`]: /// crate::types::EncryptedCredentials
/// crate::types::EncryptedCredentials pub data: String,
selfie: PassportFile,
/// Encrypted file with the front side of the document, provided by the
/// Array of encrypted files with translated versions of documents /// user. Available for `passport`, `driver_license`, `identity_card`
/// provided by the user. Available if requested for `passport`, /// and `internal_passport`. The file can be decrypted and verified
/// `driver_license`, `identity_card`, `internal_passport`, /// using the accompanying [`EncryptedCredentials`].
/// `utility_bill`, `bank_statement`, `rental_agreement`, ///
/// `passport_registration` and `temporary_registration` types. Files /// [`EncryptedCredentials`]:
/// can be decrypted and verified using the accompanying /// crate::types::EncryptedCredentials
/// [`EncryptedCredentials`]. pub front_side: PassportFile,
///
/// [`EncryptedCredentials`]: /// Encrypted file with the reverse side of the document, provided by
/// crate::types::EncryptedCredentials /// the user. Available for `driver_license` and `identity_card`. The
translation: Option<Vec<PassportFile>>, /// file can be decrypted and verified using the accompanying
}, /// [`EncryptedCredentials`].
InternalPassport { ///
/// Base64-encoded encrypted Telegram Passport element data provided /// [`EncryptedCredentials`]:
/// by the user, available for `personal_details`, `passport`, /// crate::types::EncryptedCredentials
/// `driver_license`, `identity_card`, `internal_passport` and pub reverse_side: PassportFile,
/// `address` types. Can be decrypted and verified using the
/// accompanying [`EncryptedCredentials`]. /// Encrypted file with the selfie of the user holding a document,
/// /// provided by the user; available for `passport`, `driver_license`,
/// [`EncryptedCredentials`]: /// `identity_card` and `internal_passport`. The file can be decrypted
/// crate::types::EncryptedCredentials /// and verified using the accompanying [`EncryptedCredentials`].
data: String, ///
/// [`EncryptedCredentials`]:
/// Encrypted file with the front side of the document, provided by the /// crate::types::EncryptedCredentials
/// user. Available for `passport`, `driver_license`, `identity_card` pub selfie: PassportFile,
/// and `internal_passport`. The file can be decrypted and verified
/// using the accompanying [`EncryptedCredentials`]. /// Array of encrypted files with translated versions of documents
/// /// provided by the user. Available if requested for `passport`,
/// [`EncryptedCredentials`]: /// `driver_license`, `identity_card`, `internal_passport`,
/// crate::types::EncryptedCredentials /// `utility_bill`, `bank_statement`, `rental_agreement`,
front_side: PassportFile, /// `passport_registration` and `temporary_registration` types. Files
/// can be decrypted and verified using the accompanying
/// Encrypted file with the selfie of the user holding a document, /// [`EncryptedCredentials`].
/// provided by the user; available for `passport`, `driver_license`, ///
/// `identity_card` and `internal_passport`. The file can be decrypted /// [`EncryptedCredentials`]:
/// and verified using the accompanying [`EncryptedCredentials`]. /// crate::types::EncryptedCredentials
/// pub translation: Option<Vec<PassportFile>>,
/// [`EncryptedCredentials`]: }
/// crate::types::EncryptedCredentials
selfie: PassportFile, #[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
/// Array of encrypted files with translated versions of documents
/// provided by the user. Available if requested for `passport`, pub struct EncryptedPassportElementInternalPassport {
/// `driver_license`, `identity_card`, `internal_passport`, /// Base64-encoded encrypted Telegram Passport element data provided
/// `utility_bill`, `bank_statement`, `rental_agreement`, /// by the user, available for `personal_details`, `passport`,
/// `passport_registration` and `temporary_registration` types. Files /// `driver_license`, `identity_card`, `internal_passport` and
/// can be decrypted and verified using the accompanying /// `address` types. Can be decrypted and verified using the
/// [`EncryptedCredentials`]. /// accompanying [`EncryptedCredentials`].
/// ///
/// [`EncryptedCredentials`]: /// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials /// crate::types::EncryptedCredentials
translation: Option<Vec<PassportFile>>, pub data: String,
},
Address { /// Encrypted file with the front side of the document, provided by the
/// Base64-encoded encrypted Telegram Passport element data provided /// user. Available for `passport`, `driver_license`, `identity_card`
/// by the user, available for `personal_details`, `passport`, /// and `internal_passport`. The file can be decrypted and verified
/// `driver_license`, `identity_card`, `internal_passport` and /// using the accompanying [`EncryptedCredentials`].
/// `address` types. Can be decrypted and verified using the ///
/// accompanying [`EncryptedCredentials`]. /// [`EncryptedCredentials`]:
/// /// crate::types::EncryptedCredentials
/// [`EncryptedCredentials`]: pub front_side: PassportFile,
/// crate::types::EncryptedCredentials
data: String, /// Encrypted file with the selfie of the user holding a document,
}, /// provided by the user; available for `passport`, `driver_license`,
UtilityBill { /// `identity_card` and `internal_passport`. The file can be decrypted
/// Array of encrypted files with documents provided by the user, /// and verified using the accompanying [`EncryptedCredentials`].
/// available for `utility_bill`, `bank_statement`, `rental_agreement`, ///
/// `passport_registration` and `temporary_registration` types. Files /// [`EncryptedCredentials`]:
/// can be decrypted and verified using the accompanying /// crate::types::EncryptedCredentials
/// [`EncryptedCredentials`]. pub selfie: PassportFile,
///
/// [`EncryptedCredentials`]: /// Array of encrypted files with translated versions of documents
/// crate::types::EncryptedCredentials /// provided by the user. Available if requested for `passport`,
files: Vec<PassportFile>, /// `driver_license`, `identity_card`, `internal_passport`,
/// `utility_bill`, `bank_statement`, `rental_agreement`,
/// Array of encrypted files with translated versions of documents /// `passport_registration` and `temporary_registration` types. Files
/// provided by the user. Available if requested for `passport`, /// can be decrypted and verified using the accompanying
/// `driver_license`, `identity_card`, `internal_passport`, /// [`EncryptedCredentials`].
/// `utility_bill`, `bank_statement`, `rental_agreement`, ///
/// `passport_registration` and `temporary_registration` types. Files /// [`EncryptedCredentials`]:
/// can be decrypted and verified using the accompanying /// crate::types::EncryptedCredentials
/// [`EncryptedCredentials`]. pub translation: Option<Vec<PassportFile>>,
/// }
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials #[serde_with_macros::skip_serializing_none]
translation: Option<Vec<PassportFile>>, #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
}, pub struct EncryptedPassportElementAddress {
BankStatement { /// Base64-encoded encrypted Telegram Passport element data provided
/// Array of encrypted files with documents provided by the user, /// by the user, available for `personal_details`, `passport`,
/// available for `utility_bill`, `bank_statement`, `rental_agreement`, /// `driver_license`, `identity_card`, `internal_passport` and
/// `passport_registration` and `temporary_registration` types. Files /// `address` types. Can be decrypted and verified using the
/// can be decrypted and verified using the accompanying /// accompanying [`EncryptedCredentials`].
/// [`EncryptedCredentials`]. ///
/// /// [`EncryptedCredentials`]:
/// [`EncryptedCredentials`]: /// crate::types::EncryptedCredentials
/// crate::types::EncryptedCredentials pub data: String,
files: Vec<PassportFile>, }
/// Array of encrypted files with translated versions of documents #[serde_with_macros::skip_serializing_none]
/// provided by the user. Available if requested for `passport`, #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
/// `driver_license`, `identity_card`, `internal_passport`, pub struct EncryptedPassportElementUtilityBill {
/// `utility_bill`, `bank_statement`, `rental_agreement`, /// Array of encrypted files with documents provided by the user,
/// `passport_registration` and `temporary_registration` types. Files /// available for `utility_bill`, `bank_statement`, `rental_agreement`,
/// can be decrypted and verified using the accompanying /// `passport_registration` and `temporary_registration` types. Files
/// [`EncryptedCredentials`]. /// can be decrypted and verified using the accompanying
/// /// [`EncryptedCredentials`].
/// [`EncryptedCredentials`]: ///
/// crate::types::EncryptedCredentials /// [`EncryptedCredentials`]:
translation: Option<Vec<PassportFile>>, /// crate::types::EncryptedCredentials
}, pub files: Vec<PassportFile>,
RentalAgreement {
/// Array of encrypted files with documents provided by the user, /// Array of encrypted files with translated versions of documents
/// available for `utility_bill`, `bank_statement`, `rental_agreement`, /// provided by the user. Available if requested for `passport`,
/// `passport_registration` and `temporary_registration` types. Files /// `driver_license`, `identity_card`, `internal_passport`,
/// can be decrypted and verified using the accompanying /// `utility_bill`, `bank_statement`, `rental_agreement`,
/// [`EncryptedCredentials`]. /// `passport_registration` and `temporary_registration` types. Files
/// /// can be decrypted and verified using the accompanying
/// [`EncryptedCredentials`]: /// [`EncryptedCredentials`].
/// crate::types::EncryptedCredentials ///
files: Vec<PassportFile>, /// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
/// Array of encrypted files with translated versions of documents pub translation: Option<Vec<PassportFile>>,
/// provided by the user. Available if requested for `passport`, }
/// `driver_license`, `identity_card`, `internal_passport`,
/// `utility_bill`, `bank_statement`, `rental_agreement`, #[serde_with_macros::skip_serializing_none]
/// `passport_registration` and `temporary_registration` types. Files #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
/// can be decrypted and verified using the accompanying
/// [`EncryptedCredentials`]. pub struct EncryptedPassportElementBankStatement {
/// /// Array of encrypted files with documents provided by the user,
/// [`EncryptedCredentials`]: /// available for `utility_bill`, `bank_statement`, `rental_agreement`,
/// crate::types::EncryptedCredentials /// `passport_registration` and `temporary_registration` types. Files
translation: Option<Vec<PassportFile>>, /// can be decrypted and verified using the accompanying
}, /// [`EncryptedCredentials`].
PassportRegistration { ///
/// Array of encrypted files with documents provided by the user, /// [`EncryptedCredentials`]:
/// available for `utility_bill`, `bank_statement`, `rental_agreement`, /// crate::types::EncryptedCredentials
/// `passport_registration` and `temporary_registration` types. Files pub files: Vec<PassportFile>,
/// can be decrypted and verified using the accompanying
/// [`EncryptedCredentials`]. /// Array of encrypted files with translated versions of documents
/// /// provided by the user. Available if requested for `passport`,
/// [`EncryptedCredentials`]: /// `driver_license`, `identity_card`, `internal_passport`,
/// crate::types::EncryptedCredentials /// `utility_bill`, `bank_statement`, `rental_agreement`,
files: Vec<PassportFile>, /// `passport_registration` and `temporary_registration` types. Files
/// can be decrypted and verified using the accompanying
/// Array of encrypted files with translated versions of documents /// [`EncryptedCredentials`].
/// provided by the user. Available if requested for `passport`, ///
/// `driver_license`, `identity_card`, `internal_passport`, /// [`EncryptedCredentials`]:
/// `utility_bill`, `bank_statement`, `rental_agreement`, /// crate::types::EncryptedCredentials
/// `passport_registration` and `temporary_registration` types. Files pub translation: Option<Vec<PassportFile>>,
/// can be decrypted and verified using the accompanying }
/// [`EncryptedCredentials`].
/// #[serde_with_macros::skip_serializing_none]
/// [`EncryptedCredentials`]: #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
/// crate::types::EncryptedCredentials pub struct EncryptedPassportElementRentalAgreement {
translation: Option<Vec<PassportFile>>, /// Array of encrypted files with documents provided by the user,
}, /// available for `utility_bill`, `bank_statement`, `rental_agreement`,
TemporaryRegistration { /// `passport_registration` and `temporary_registration` types. Files
/// Array of encrypted files with documents provided by the user, /// can be decrypted and verified using the accompanying
/// available for `utility_bill`, `bank_statement`, `rental_agreement`, /// [`EncryptedCredentials`].
/// `passport_registration` and `temporary_registration` types. Files ///
/// can be decrypted and verified using the accompanying /// [`EncryptedCredentials`]:
/// [`EncryptedCredentials`]. /// crate::types::EncryptedCredentials
/// pub files: Vec<PassportFile>,
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials /// Array of encrypted files with translated versions of documents
files: Vec<PassportFile>, /// provided by the user. Available if requested for `passport`,
/// `driver_license`, `identity_card`, `internal_passport`,
/// Array of encrypted files with translated versions of documents /// `utility_bill`, `bank_statement`, `rental_agreement`,
/// provided by the user. Available if requested for `passport`, /// `passport_registration` and `temporary_registration` types. Files
/// `driver_license`, `identity_card`, `internal_passport`, /// can be decrypted and verified using the accompanying
/// `utility_bill`, `bank_statement`, `rental_agreement`, /// [`EncryptedCredentials`].
/// `passport_registration` and `temporary_registration` types. Files ///
/// can be decrypted and verified using the accompanying /// [`EncryptedCredentials`]:
/// [`EncryptedCredentials`]. /// crate::types::EncryptedCredentials
/// pub translation: Option<Vec<PassportFile>>,
/// [`EncryptedCredentials`]: }
/// crate::types::EncryptedCredentials
translation: Option<Vec<PassportFile>>, #[serde_with_macros::skip_serializing_none]
}, #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
PhoneNumber {
/// User's verified phone number, available only for `phone_number` pub struct EncryptedPassportElementPassportRegistration {
/// type. /// Array of encrypted files with documents provided by the user,
phone_number: String, /// available for `utility_bill`, `bank_statement`, `rental_agreement`,
}, /// `passport_registration` and `temporary_registration` types. Files
Email { /// can be decrypted and verified using the accompanying
/// User's verified email address, available only for `email` type. /// [`EncryptedCredentials`].
email: String, ///
}, /// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
pub files: Vec<PassportFile>,
/// Array of encrypted files with translated versions of documents
/// provided by the user. Available if requested for `passport`,
/// `driver_license`, `identity_card`, `internal_passport`,
/// `utility_bill`, `bank_statement`, `rental_agreement`,
/// `passport_registration` and `temporary_registration` types. Files
/// can be decrypted and verified using the accompanying
/// [`EncryptedCredentials`].
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
pub translation: Option<Vec<PassportFile>>,
}
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct EncryptedPassportElementTemporaryRegistration {
/// Array of encrypted files with documents provided by the user,
/// available for `utility_bill`, `bank_statement`, `rental_agreement`,
/// `passport_registration` and `temporary_registration` types. Files
/// can be decrypted and verified using the accompanying
/// [`EncryptedCredentials`].
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
pub files: Vec<PassportFile>,
/// Array of encrypted files with translated versions of documents
/// provided by the user. Available if requested for `passport`,
/// `driver_license`, `identity_card`, `internal_passport`,
/// `utility_bill`, `bank_statement`, `rental_agreement`,
/// `passport_registration` and `temporary_registration` types. Files
/// can be decrypted and verified using the accompanying
/// [`EncryptedCredentials`].
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
pub translation: Option<Vec<PassportFile>>,
}
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct EncryptedPassportElementPhoneNumber {
/// User's verified phone number, available only for `phone_number`
/// type.
pub phone_number: String,
}
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct EncryptedPassportElementEmail {
/// User's verified email address, available only for `email` type.
pub email: String,
} }

View file

@ -59,6 +59,7 @@ mod tests {
use crate::types::{ use crate::types::{
inline_keyboard_markup::InlineKeyboardMarkup, parse_mode::ParseMode, inline_keyboard_markup::InlineKeyboardMarkup, parse_mode::ParseMode,
InlineQueryResult, InlineQueryResultCachedAudio, InputMessageContent, InlineQueryResult, InlineQueryResultCachedAudio, InputMessageContent,
InputMessageContentText,
}; };
#[test] #[test]
@ -89,11 +90,13 @@ mod tests {
caption: Some(String::from("caption")), caption: Some(String::from("caption")),
parse_mode: Some(ParseMode::HTML), parse_mode: Some(ParseMode::HTML),
reply_markup: Some(InlineKeyboardMarkup::default()), reply_markup: Some(InlineKeyboardMarkup::default()),
input_message_content: Some(InputMessageContent::Text { input_message_content: Some(InputMessageContent::Text(
message_text: String::from("message_text"), InputMessageContentText {
parse_mode: Some(ParseMode::MarkdownV2), message_text: String::from("message_text"),
disable_web_page_preview: Some(true), parse_mode: Some(ParseMode::MarkdownV2),
}), disable_web_page_preview: Some(true),
},
)),
}); });
let expected_json = r#"{"type":"audio","id":"id","audio_file_id":"audio_file_id","caption":"caption","parse_mode":"HTML","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","disable_web_page_preview":true}}"#; let expected_json = r#"{"type":"audio","id":"id","audio_file_id":"audio_file_id","caption":"caption","parse_mode":"HTML","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","disable_web_page_preview":true}}"#;

View file

@ -3,7 +3,6 @@ use serde::{Deserialize, Serialize};
use crate::types::{InputFile, ParseMode}; use crate::types::{InputFile, ParseMode};
// TODO: should variants use new-type? // TODO: should variants use new-type?
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type")] #[serde(tag = "type")]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
@ -11,169 +10,185 @@ use crate::types::{InputFile, ParseMode};
/// ///
/// [The official docs](https://core.telegram.org/bots/api#inputmedia). /// [The official docs](https://core.telegram.org/bots/api#inputmedia).
pub enum InputMedia { pub enum InputMedia {
/// Represents a photo to be sent. Photo(InputMediaPhoto),
Video(InputMediaVideo),
Animation(InputMediaAnimation),
Audio(InputMediaAudio),
Document(InputMediaDocument),
}
/// Represents a photo to be sent.
///
/// [The official docs](https://core.telegram.org/bots/api#inputmediaphoto).
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct InputMediaPhoto {
/// File to send.
pub media: InputFile,
/// Caption of the photo to be sent, 0-1024 characters.
pub caption: Option<String>,
/// Send [Markdown] or [HTML], if you want Telegram apps to show [bold,
/// italic, fixed-width text or inline URLs] in the media caption.
/// ///
/// [The official docs](https://core.telegram.org/bots/api#inputmediaphoto). /// [Markdown]: https://core.telegram.org/bots/api#markdown-style
Photo { /// [HTML]: https://core.telegram.org/bots/api#html-style
/// File to send. /// [bold, italic, fixed-width text or inline URLs]: https://core.telegram.org/bots/api#formatting-options
media: InputFile, pub parse_mode: Option<ParseMode>,
}
/// Caption of the photo to be sent, 0-1024 characters. /// Represents a video to be sent.
caption: Option<String>, ///
/// [The official docs](https://core.telegram.org/bots/api#inputmediavideo).
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct InputMediaVideo {
// File to send.
pub media: InputFile,
/// Send [Markdown] or [HTML], if you want Telegram apps to show [bold, /// Thumbnail of the file sent; can be ignored if thumbnail generation
/// italic, fixed-width text or inline URLs] in the media caption. /// for the file is supported server-side. The thumbnail should be in
/// /// JPEG format and less than 200 kB in size. A thumbnails width and
/// [Markdown]: https://core.telegram.org/bots/api#markdown-style /// height should not exceed 320. Ignored if the file is not uploaded
/// [HTML]: https://core.telegram.org/bots/api#html-style /// using multipart/form-data.
/// [bold, italic, fixed-width text or inline URLs]: https://core.telegram.org/bots/api#formatting-options pub thumb: Option<InputFile>,
parse_mode: Option<ParseMode>,
},
/// Represents a video to be sent. /// Caption of the video to be sent, 0-1024 characters.
pub caption: Option<String>,
/// Send [Markdown] or [HTML], if you want Telegram apps to show [bold,
/// italic, fixed-width text or inline URLs] in the media caption.
/// ///
/// [The official docs](https://core.telegram.org/bots/api#inputmediavideo). /// [Markdown]: https://core.telegram.org/bots/api#markdown-style
Video { /// [HTML]: https://core.telegram.org/bots/api#html-style
// File to send. /// [bold, italic, fixed-width text or inline URLs]: https://core.telegram.org/bots/api#formatting-options
media: InputFile, pub parse_mode: Option<ParseMode>,
/// Thumbnail of the file sent; can be ignored if thumbnail generation /// Video width.
/// for the file is supported server-side. The thumbnail should be in pub width: Option<u16>,
/// JPEG format and less than 200 kB in size. A thumbnails width and
/// height should not exceed 320. Ignored if the file is not uploaded
/// using multipart/form-data.
thumb: Option<InputFile>,
/// Caption of the video to be sent, 0-1024 characters. /// Video height.
caption: Option<String>, pub height: Option<u16>,
/// Send [Markdown] or [HTML], if you want Telegram apps to show [bold, /// Video duration.
/// italic, fixed-width text or inline URLs] in the media caption. pub duration: Option<u16>,
///
/// [Markdown]: https://core.telegram.org/bots/api#markdown-style
/// [HTML]: https://core.telegram.org/bots/api#html-style
/// [bold, italic, fixed-width text or inline URLs]: https://core.telegram.org/bots/api#formatting-options
parse_mode: Option<ParseMode>,
/// Video width. /// Pass `true`, if the uploaded video is suitable for streaming.
width: Option<u16>, pub supports_streaming: Option<bool>,
}
/// Video height. /// Represents an animation file (GIF or H.264/MPEG-4 AVC video without
height: Option<u16>, /// sound) to be sent.
///
/// [The official docs](https://core.telegram.org/bots/api#inputmediaanimation).
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct InputMediaAnimation {
/// File to send.
pub media: InputFile,
/// Video duration. /// Thumbnail of the file sent; can be ignored if thumbnail generation
duration: Option<u16>, /// for the file is supported server-side. The thumbnail should be in
/// JPEG format and less than 200 kB in size. A thumbnails width and
/// height should not exceed 320. Ignored if the file is not uploaded
/// using multipart/form-data.
pub thumb: Option<InputFile>,
/// Pass `true`, if the uploaded video is suitable for streaming. /// Caption of the animation to be sent, 0-1024 characters.
supports_streaming: Option<bool>, pub caption: Option<String>,
},
/// Represents an animation file (GIF or H.264/MPEG-4 AVC video without /// Send [Markdown] or [HTML], if you want Telegram apps to show [bold,
/// sound) to be sent. /// italic, fixed-width text or inline URLs] in the media caption.
/// ///
/// [The official docs](https://core.telegram.org/bots/api#inputmediaanimation). /// [Markdown]: https://core.telegram.org/bots/api#markdown-style
Animation { /// [HTML]: https://core.telegram.org/bots/api#html-style
/// File to send. /// [bold, italic, fixed-width text or inline URLs]: https://core.telegram.org/bots/api#formatting-options
media: InputFile, pub parse_mode: Option<ParseMode>,
/// Thumbnail of the file sent; can be ignored if thumbnail generation /// Animation width.
/// for the file is supported server-side. The thumbnail should be in pub width: Option<u16>,
/// JPEG format and less than 200 kB in size. A thumbnails width and
/// height should not exceed 320. Ignored if the file is not uploaded
/// using multipart/form-data.
thumb: Option<InputFile>,
/// Caption of the animation to be sent, 0-1024 characters. /// Animation height.
caption: Option<String>, pub height: Option<u16>,
/// Send [Markdown] or [HTML], if you want Telegram apps to show [bold, /// Animation duration.
/// italic, fixed-width text or inline URLs] in the media caption. pub duration: Option<u16>,
/// }
/// [Markdown]: https://core.telegram.org/bots/api#markdown-style
/// [HTML]: https://core.telegram.org/bots/api#html-style
/// [bold, italic, fixed-width text or inline URLs]: https://core.telegram.org/bots/api#formatting-options
parse_mode: Option<ParseMode>,
/// Animation width. /// Represents an audio file to be treated as music to be sent.
width: Option<u16>, ///
/// [The official docs](https://core.telegram.org/bots/api#inputmediaaudio).
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct InputMediaAudio {
/// File to send.
pub media: InputFile,
/// Animation height. /// Thumbnail of the file sent; can be ignored if thumbnail generation
height: Option<u16>, /// for the file is supported server-side. The thumbnail should be in
/// JPEG format and less than 200 kB in size. A thumbnails width and
/// height should not exceed 320. Ignored if the file is not uploaded
/// using multipart/form-data.
pub thumb: Option<InputFile>,
/// Animation duration. /// Caption of the audio to be sent, 0-1024 characters.
duration: Option<u16>, pub caption: Option<String>,
},
/// Represents an audio file to be treated as music to be sent. /// Send [Markdown] or [HTML], if you want Telegram apps to show [bold,
/// italic, fixed-width text or inline URLs] in the media caption.
/// ///
/// [The official docs](https://core.telegram.org/bots/api#inputmediaaudio). /// [Markdown]: https://core.telegram.org/bots/api#markdown-style
Audio { /// [HTML]: https://core.telegram.org/bots/api#html-style
/// File to send. /// [bold, italic, fixed-width text or inline URLs]: https://core.telegram.org/bots/api#formatting-options
media: InputFile, pub parse_mode: Option<String>,
/// Thumbnail of the file sent; can be ignored if thumbnail generation /// Duration of the audio in seconds.
/// for the file is supported server-side. The thumbnail should be in pub duration: Option<u16>,
/// JPEG format and less than 200 kB in size. A thumbnails width and
/// height should not exceed 320. Ignored if the file is not uploaded
/// using multipart/form-data.
thumb: Option<InputFile>,
/// Caption of the audio to be sent, 0-1024 characters. /// Performer of the audio.
caption: Option<String>, pub performer: Option<String>,
/// Send [Markdown] or [HTML], if you want Telegram apps to show [bold, /// Title of the audio.
/// italic, fixed-width text or inline URLs] in the media caption. pub title: Option<String>,
/// }
/// [Markdown]: https://core.telegram.org/bots/api#markdown-style
/// [HTML]: https://core.telegram.org/bots/api#html-style
/// [bold, italic, fixed-width text or inline URLs]: https://core.telegram.org/bots/api#formatting-options
parse_mode: Option<String>,
/// Duration of the audio in seconds. /// Represents a general file to be sent.
duration: Option<u16>, ///
/// [The official docs](https://core.telegram.org/bots/api#inputmediadocument).
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct InputMediaDocument {
/// File to send.
pub media: InputFile,
/// Performer of the audio. /// Thumbnail of the file sent; can be ignored if thumbnail generation
performer: Option<String>, /// for the file is supported server-side. The thumbnail should be in
/// JPEG format and less than 200 kB in size. A thumbnails width and
/// height should not exceed 320. Ignored if the file is not uploaded
/// using multipart/form-data.
pub thumb: Option<InputFile>,
/// Title of the audio. /// Caption of the document to be sent, 0-1024 charactersю
title: Option<String>, pub caption: Option<String>,
},
/// Represents a general file to be sent. /// Send [Markdown] or [HTML], if you want Telegram apps to show [bold,
/// italic, fixed-width text or inline URLs] in the media caption.
/// ///
/// [The official docs](https://core.telegram.org/bots/api#inputmediadocument). /// [Markdown]: https://core.telegram.org/bots/api#markdown-style
Document { /// [HTML]: https://core.telegram.org/bots/api#html-style
/// File to send. /// [bold, italic, fixed-width text or inline URLs]: https://core.telegram.org/bots/api#formatting-options
media: InputFile, pub parse_mode: Option<ParseMode>,
/// Thumbnail of the file sent; can be ignored if thumbnail generation
/// for the file is supported server-side. The thumbnail should be in
/// JPEG format and less than 200 kB in size. A thumbnails width and
/// height should not exceed 320. Ignored if the file is not uploaded
/// using multipart/form-data.
thumb: Option<InputFile>,
/// Caption of the document to be sent, 0-1024 charactersю
caption: Option<String>,
/// Send [Markdown] or [HTML], if you want Telegram apps to show [bold,
/// italic, fixed-width text or inline URLs] in the media caption.
///
/// [Markdown]: https://core.telegram.org/bots/api#markdown-style
/// [HTML]: https://core.telegram.org/bots/api#html-style
/// [bold, italic, fixed-width text or inline URLs]: https://core.telegram.org/bots/api#formatting-options
parse_mode: Option<ParseMode>,
},
} }
impl InputMedia { impl InputMedia {
pub fn media(&self) -> &InputFile { pub fn media(&self) -> &InputFile {
match self { match self {
InputMedia::Photo { media, .. } InputMedia::Photo(InputMediaPhoto { media, .. })
| InputMedia::Document { media, .. } | InputMedia::Document(InputMediaDocument { media, .. })
| InputMedia::Audio { media, .. } | InputMedia::Audio(InputMediaAudio { media, .. })
| InputMedia::Animation { media, .. } | InputMedia::Animation(InputMediaAnimation { media, .. })
| InputMedia::Video { media, .. } => media, | InputMedia::Video(InputMediaVideo { media, .. }) => media,
} }
} }
} }
@ -181,11 +196,11 @@ impl InputMedia {
impl From<InputMedia> for InputFile { impl From<InputMedia> for InputFile {
fn from(media: InputMedia) -> InputFile { fn from(media: InputMedia) -> InputFile {
match media { match media {
InputMedia::Photo { media, .. } InputMedia::Photo(InputMediaPhoto { media, .. })
| InputMedia::Document { media, .. } | InputMedia::Document(InputMediaDocument { media, .. })
| InputMedia::Audio { media, .. } | InputMedia::Audio(InputMediaAudio { media, .. })
| InputMedia::Animation { media, .. } | InputMedia::Animation(InputMediaAnimation { media, .. })
| InputMedia::Video { media, .. } => media, | InputMedia::Video(InputMediaVideo { media, .. }) => media,
} }
} }
} }
@ -197,11 +212,11 @@ mod tests {
#[test] #[test]
fn photo_serialize() { fn photo_serialize() {
let expected_json = r#"{"type":"photo","media":"123456"}"#; let expected_json = r#"{"type":"photo","media":"123456"}"#;
let photo = InputMedia::Photo { let photo = InputMedia::Photo(InputMediaPhoto {
media: InputFile::FileId(String::from("123456")), media: InputFile::FileId(String::from("123456")),
caption: None, caption: None,
parse_mode: None, parse_mode: None,
}; });
let actual_json = serde_json::to_string(&photo).unwrap(); let actual_json = serde_json::to_string(&photo).unwrap();
assert_eq!(expected_json, actual_json); assert_eq!(expected_json, actual_json);
@ -210,7 +225,7 @@ mod tests {
#[test] #[test]
fn video_serialize() { fn video_serialize() {
let expected_json = r#"{"type":"video","media":"123456"}"#; let expected_json = r#"{"type":"video","media":"123456"}"#;
let video = InputMedia::Video { let video = InputMedia::Video(InputMediaVideo {
media: InputFile::FileId(String::from("123456")), media: InputFile::FileId(String::from("123456")),
thumb: None, thumb: None,
caption: None, caption: None,
@ -219,7 +234,7 @@ mod tests {
height: None, height: None,
duration: None, duration: None,
supports_streaming: None, supports_streaming: None,
}; });
let actual_json = serde_json::to_string(&video).unwrap(); let actual_json = serde_json::to_string(&video).unwrap();
assert_eq!(expected_json, actual_json); assert_eq!(expected_json, actual_json);
@ -228,7 +243,7 @@ mod tests {
#[test] #[test]
fn animation_serialize() { fn animation_serialize() {
let expected_json = r#"{"type":"animation","media":"123456"}"#; let expected_json = r#"{"type":"animation","media":"123456"}"#;
let video = InputMedia::Animation { let video = InputMedia::Animation(InputMediaAnimation {
media: InputFile::FileId(String::from("123456")), media: InputFile::FileId(String::from("123456")),
thumb: None, thumb: None,
caption: None, caption: None,
@ -236,7 +251,7 @@ mod tests {
width: None, width: None,
height: None, height: None,
duration: None, duration: None,
}; });
let actual_json = serde_json::to_string(&video).unwrap(); let actual_json = serde_json::to_string(&video).unwrap();
assert_eq!(expected_json, actual_json); assert_eq!(expected_json, actual_json);
@ -245,7 +260,7 @@ mod tests {
#[test] #[test]
fn audio_serialize() { fn audio_serialize() {
let expected_json = r#"{"type":"audio","media":"123456"}"#; let expected_json = r#"{"type":"audio","media":"123456"}"#;
let video = InputMedia::Audio { let video = InputMedia::Audio(InputMediaAudio {
media: InputFile::FileId(String::from("123456")), media: InputFile::FileId(String::from("123456")),
thumb: None, thumb: None,
caption: None, caption: None,
@ -253,7 +268,7 @@ mod tests {
duration: None, duration: None,
performer: None, performer: None,
title: None, title: None,
}; });
let actual_json = serde_json::to_string(&video).unwrap(); let actual_json = serde_json::to_string(&video).unwrap();
assert_eq!(expected_json, actual_json); assert_eq!(expected_json, actual_json);
@ -262,12 +277,12 @@ mod tests {
#[test] #[test]
fn document_serialize() { fn document_serialize() {
let expected_json = r#"{"type":"document","media":"123456"}"#; let expected_json = r#"{"type":"document","media":"123456"}"#;
let video = InputMedia::Document { let video = InputMedia::Document(InputMediaDocument {
media: InputFile::FileId(String::from("123456")), media: InputFile::FileId(String::from("123456")),
thumb: None, thumb: None,
caption: None, caption: None,
parse_mode: None, parse_mode: None,
}; });
let actual_json = serde_json::to_string(&video).unwrap(); let actual_json = serde_json::to_string(&video).unwrap();
assert_eq!(expected_json, actual_json); assert_eq!(expected_json, actual_json);

View file

@ -2,88 +2,100 @@ use serde::{Deserialize, Serialize};
use crate::types::ParseMode; use crate::types::ParseMode;
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
/// This object represents the content of a message to be sent as a result of an /// This object represents the content of a message to be sent as a result of an
/// inline query. /// inline query.
/// ///
/// [The official docs](https://core.telegram.org/bots/api#inputmessagecontent). /// [The official docs](https://core.telegram.org/bots/api#inputmessagecontent).
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum InputMessageContent { pub enum InputMessageContent {
/// Represents the content of a text message to be sent as the result of an Text(InputMessageContentText),
/// inline query. Location(InputMessageContentLocation),
Text { Venue(InputMessageContentVenue),
/// Text of the message to be sent, 1-4096 characters. Contact(InputMessageContentContact),
message_text: String, }
/// Represents the content of a text message to be sent as the result of an
/// inline query.
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct InputMessageContentText {
/// Text of the message to be sent, 1-4096 characters.
pub message_text: String,
/// Send [Markdown] or [HTML], if you want Telegram apps to show [bold, /// Send [Markdown] or [HTML], if you want Telegram apps to show [bold,
/// italic, fixed-width text or inline URLs] in the media caption. /// italic, fixed-width text or inline URLs] in the media caption.
/// ///
/// [Markdown]: https://core.telegram.org/bots/api#markdown-style /// [Markdown]: https://core.telegram.org/bots/api#markdown-style
/// [HTML]: https://core.telegram.org/bots/api#html-style /// [HTML]: https://core.telegram.org/bots/api#html-style
/// [bold, italic, fixed-width text or inline URLs]: https://core.telegram.org/bots/api#formatting-options /// [bold, italic, fixed-width text or inline URLs]: https://core.telegram.org/bots/api#formatting-options
parse_mode: Option<ParseMode>, pub parse_mode: Option<ParseMode>,
/// Disables link previews for links in the sent message. /// Disables link previews for links in the sent message.
disable_web_page_preview: Option<bool>, pub disable_web_page_preview: Option<bool>,
}, }
/// Represents the content of a location message to be sent as the result /// Represents the content of a location message to be sent as the result of an
/// of an inline query. /// inline query.
Location { #[serde_with_macros::skip_serializing_none]
/// Latitude of the location in degrees. #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
latitude: f64, pub struct InputMessageContentLocation {
/// Latitude of the location in degrees.
pub latitude: f64,
/// Longitude of the location in degrees. /// Longitude of the location in degrees.
longitude: f64, pub longitude: f64,
/// Period in seconds for which the location can be updated, should be /// Period in seconds for which the location can be updated, should be
/// between 60 and 86400. /// between 60 and 86400.
live_period: Option<u32>, pub live_period: Option<u32>,
}, }
/// Represents the content of a venue message to be sent as the result of /// Represents the content of a venue message to be sent as the result of
/// an inline query. /// an inline query.
Venue { #[serde_with_macros::skip_serializing_none]
/// Latitude of the venue in degrees. #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
latitude: f64,
/// Longitude of the venue in degrees. pub struct InputMessageContentVenue {
longitude: f64, /// Latitude of the venue in degrees.
pub latitude: f64,
/// Name of the venue. /// Longitude of the venue in degrees.
title: String, pub longitude: f64,
/// Address of the venue. /// Name of the venue.
address: String, pub title: String,
/// Foursquare identifier of the venue, if known. /// Address of the venue.
foursquare_id: Option<String>, pub address: String,
/// Foursquare type of the venue, if known. (For example, /// Foursquare identifier of the venue, if known.
/// `arts_entertainment/default`, `arts_entertainment/aquarium` pub foursquare_id: Option<String>,
/// or `food/icecream`.)
foursquare_type: Option<String>,
},
/// Represents the content of a contact message to be sent as the result of /// Foursquare type of the venue, if known. (For example,
/// an inline query. /// `arts_entertainment/default`, `arts_entertainment/aquarium`
Contact { /// or `food/icecream`.)
/// Contact's phone number. pub foursquare_type: Option<String>,
phone_number: String, }
/// Contact's first name. /// Represents the content of a contact message to be sent as the result of
first_name: String, /// an inline query.
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct InputMessageContentContact {
/// Contact's phone number.
pub phone_number: String,
/// Contact's last name. /// Contact's first name.
last_name: Option<String>, pub first_name: String,
/// Additional data about the contact in the form of a [vCard], 0-2048 /// Contact's last name.
/// bytes. pub last_name: Option<String>,
///
/// [vCard]: https://en.wikipedia.org/wiki/VCard /// Additional data about the contact in the form of a [vCard], 0-2048
vcard: Option<String>, /// bytes.
}, ///
/// [vCard]: https://en.wikipedia.org/wiki/VCard
pub vcard: Option<String>,
} }
#[cfg(test)] #[cfg(test)]
@ -93,11 +105,11 @@ mod tests {
#[test] #[test]
fn text_serialize() { fn text_serialize() {
let expected_json = r#"{"message_text":"text"}"#; let expected_json = r#"{"message_text":"text"}"#;
let text_content = InputMessageContent::Text { let text_content = InputMessageContent::Text(InputMessageContentText {
message_text: String::from("text"), message_text: String::from("text"),
parse_mode: None, parse_mode: None,
disable_web_page_preview: None, disable_web_page_preview: None,
}; });
let actual_json = serde_json::to_string(&text_content).unwrap(); let actual_json = serde_json::to_string(&text_content).unwrap();
assert_eq!(expected_json, actual_json); assert_eq!(expected_json, actual_json);
@ -106,11 +118,12 @@ mod tests {
#[test] #[test]
fn location_serialize() { fn location_serialize() {
let expected_json = r#"{"latitude":59.08,"longitude":38.4326}"#; let expected_json = r#"{"latitude":59.08,"longitude":38.4326}"#;
let location_content = InputMessageContent::Location { let location_content =
latitude: 59.08, InputMessageContent::Location(InputMessageContentLocation {
longitude: 38.4326, latitude: 59.08,
live_period: None, longitude: 38.4326,
}; live_period: None,
});
let actual_json = serde_json::to_string(&location_content).unwrap(); let actual_json = serde_json::to_string(&location_content).unwrap();
assert_eq!(expected_json, actual_json); assert_eq!(expected_json, actual_json);
@ -119,14 +132,15 @@ mod tests {
#[test] #[test]
fn venue_serialize() { fn venue_serialize() {
let expected_json = r#"{"latitude":59.08,"longitude":38.4326,"title":"some title","address":"some address"}"#; let expected_json = r#"{"latitude":59.08,"longitude":38.4326,"title":"some title","address":"some address"}"#;
let venue_content = InputMessageContent::Venue { let venue_content =
latitude: 59.08, InputMessageContent::Venue(InputMessageContentVenue {
longitude: 38.4326, latitude: 59.08,
title: String::from("some title"), longitude: 38.4326,
address: String::from("some address"), title: String::from("some title"),
foursquare_id: None, address: String::from("some address"),
foursquare_type: None, foursquare_id: None,
}; foursquare_type: None,
});
let actual_json = serde_json::to_string(&venue_content).unwrap(); let actual_json = serde_json::to_string(&venue_content).unwrap();
assert_eq!(expected_json, actual_json); assert_eq!(expected_json, actual_json);
@ -136,12 +150,13 @@ mod tests {
fn contact_serialize() { fn contact_serialize() {
let expected_json = let expected_json =
r#"{"phone_number":"+3800000000","first_name":"jhon"}"#; r#"{"phone_number":"+3800000000","first_name":"jhon"}"#;
let contact_content = InputMessageContent::Contact { let contact_content =
phone_number: String::from("+3800000000"), InputMessageContent::Contact(InputMessageContentContact {
first_name: String::from("jhon"), phone_number: String::from("+3800000000"),
last_name: None, first_name: String::from("jhon"),
vcard: None, last_name: None,
}; vcard: None,
});
let actual_json = serde_json::to_string(&contact_content).unwrap(); let actual_json = serde_json::to_string(&contact_content).unwrap();
assert_eq!(expected_json, actual_json); assert_eq!(expected_json, actual_json);

File diff suppressed because it is too large Load diff

View file

@ -50,7 +50,10 @@ impl MessageEntity {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::types::{Chat, ChatKind, ForwardKind, MediaKind, MessageKind}; use crate::types::{
Chat, ChatKind, ChatPrivate, ForwardKind, ForwardOrigin, MediaKind,
MediaText, MessageCommon, MessageKind,
};
#[test] #[test]
fn recursive_kind() { fn recursive_kind() {
@ -103,15 +106,15 @@ mod tests {
date: 0, date: 0,
chat: Chat { chat: Chat {
id: 0, id: 0,
kind: ChatKind::Private { kind: ChatKind::Private(ChatPrivate {
type_: (), type_: (),
username: None, username: None,
first_name: None, first_name: None,
last_name: None, last_name: None,
}, }),
photo: None, photo: None,
}, },
kind: MessageKind::Common { kind: MessageKind::Common(MessageCommon {
from: Some(User { from: Some(User {
id: 0, id: 0,
is_bot: false, is_bot: false,
@ -120,18 +123,20 @@ mod tests {
username: None, username: None,
language_code: None, language_code: None,
}), }),
forward_kind: ForwardKind::Origin { reply_to_message: None }, forward_kind: ForwardKind::Origin(ForwardOrigin {
reply_to_message: None,
}),
edit_date: None, edit_date: None,
media_kind: MediaKind::Text { media_kind: MediaKind::Text(MediaText {
text: "no yes no".to_string(), text: "no yes no".to_string(),
entities: vec![MessageEntity { entities: vec![MessageEntity {
kind: MessageEntityKind::Mention, kind: MessageEntityKind::Mention,
offset: 3, offset: 3,
length: 3, length: 3,
}], }],
}, }),
reply_markup: None, reply_markup: None,
}, }),
} }
} }
} }

View file

@ -17,133 +17,160 @@ pub struct PassportElementError {
#[serde(tag = "source")] #[serde(tag = "source")]
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub enum PassportElementErrorKind { pub enum PassportElementErrorKind {
/// Represents an issue in one of the data fields that was provided by the
/// user. The error is considered resolved when the field's value changes.
///
/// [The official docs](https://core.telegram.org/bots/api#passportelementerrordatafield).
#[serde(rename = "data")] #[serde(rename = "data")]
DataField { DataField(PassportElementErrorDataField),
/// The section of the user's Telegram Passport which has the error.
r#type: PassportElementErrorDataFieldType,
/// Name of the data field which has the error.
field_name: String,
/// Base64-encoded data hash.
data_hash: String,
},
/// Represents an issue with the front side of a document. The error is
/// considered resolved when the file with the front side of the document
/// changes.
///
/// [The official docs](https://core.telegram.org/bots/api#passportelementerrorfrontside).
#[serde(rename = "snake_case")] #[serde(rename = "snake_case")]
FrontSide { FrontSide(PassportElementErrorFrontSide),
/// The section of the user's Telegram Passport which has the issue.
r#type: PassportElementErrorFrontSideType,
/// Base64-encoded hash of the file with the front side of the
/// document.
file_hash: String,
},
/// Represents an issue with the reverse side of a document. The error is
/// considered resolved when the file with reverse side of the document
/// changes.
///
/// [The official docs](https://core.telegram.org/bots/api#passportelementerrorreverseside).
#[serde(rename = "snake_case")] #[serde(rename = "snake_case")]
ReverseSide { ReverseSide(PassportElementErrorReverseSide),
/// The section of the user's Telegram Passport which has the issue.
r#type: PassportElementErrorReverseSideType,
//// Base64-encoded hash of the file with the reverse side of the
//// document.
file_hash: String,
},
//// Represents an issue with the selfie with a document. The error is
//// considered resolved when the file with the selfie changes.
///
/// [The official docs](https://core.telegram.org/bots/api#passportelementerrorselfie).
#[serde(rename = "snake_case")] #[serde(rename = "snake_case")]
Selfie { Selfie(PassportElementErrorSelfie),
/// The section of the user's Telegram Passport which has the issue.
r#type: PassportElementErrorSelfieType,
/// Base64-encoded hash of the file with the selfie.
file_hash: String,
},
/// Represents an issue with a document scan. The error is considered
/// resolved when the file with the document scan changes.
///
/// [The official docs](https://core.telegram.org/bots/api#passportelementerrorfile).
#[serde(rename = "snake_case")] #[serde(rename = "snake_case")]
File { File(PassportElementErrorFile),
/// The section of the user's Telegram Passport which has the issue.
r#type: PassportElementErrorFileType,
/// Base64-encoded file hash.
file_hash: String,
},
/// Represents an issue with a list of scans. The error is considered
/// resolved when the list of files containing the scans changes.
///
/// [The official docs](https://core.telegram.org/bots/api#passportelementerrorfiles).
#[serde(rename = "snake_case")] #[serde(rename = "snake_case")]
Files { Files(PassportElementErrorFiles),
/// The section of the user's Telegram Passport which has the issue.
r#type: PassportElementErrorFilesType,
/// List of base64-encoded file hashes.
file_hashes: Vec<String>,
},
/// Represents an issue with one of the files that constitute the
/// translation of a document. The error is considered resolved when the
/// file changes.
///
/// [The official docs](https://core.telegram.org/bots/api#passportelementerrortranslationfile).
#[serde(rename = "snake_case")] #[serde(rename = "snake_case")]
TranslationFile { TranslationFile(PassportElementErrorTranslationFile),
/// Type of element of the user's Telegram Passport which has the
/// issue.
r#type: PassportElementErrorTranslationFileType,
/// Base64-encoded file hash.
file_hash: String,
},
/// Represents an issue with the translated version of a document. The
/// error is considered resolved when a file with the document translation
/// change.
///
/// [The official docs](https://core.telegram.org/bots/api#passportelementerrortranslationfiles).
#[serde(rename = "snake_case")] #[serde(rename = "snake_case")]
TranslationFiles { TranslationFiles(PassportElementErrorTranslationFiles),
/// Type of element of the user's Telegram Passport which has the issue
r#type: PassportElementErrorTranslationFilesType,
/// List of base64-encoded file hashes
file_hashes: Vec<String>,
},
/// Represents an issue in an unspecified place. The error is considered
/// resolved when new data is added.
///
/// [The official docs](https://core.telegram.org/bots/api#passportelementerrorunspecified).
#[serde(rename = "snake_case")] #[serde(rename = "snake_case")]
Unspecified { Unspecified(PassportElementErrorUnspecified),
/// Type of element of the user's Telegram Passport which has the }
/// issue.
r#type: PassportElementErrorUnspecifiedType,
/// Base64-encoded element hash. /// Represents an issue in one of the data fields that was provided by the
element_hash: String, /// user. The error is considered resolved when the field's value changes.
}, ///
/// [The official docs](https://core.telegram.org/bots/api#passportelementerrordatafield).
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub struct PassportElementErrorDataField {
/// The section of the user's Telegram Passport which has the error.
pub r#type: PassportElementErrorDataFieldType,
/// Name of the data field which has the error.
pub field_name: String,
/// Base64-encoded data hash.
pub data_hash: String,
}
/// Represents an issue with the front side of a document. The error is
/// considered resolved when the file with the front side of the document
/// changes.
///
/// [The official docs](https://core.telegram.org/bots/api#passportelementerrorfrontside).
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub struct PassportElementErrorFrontSide {
/// The section of the user's Telegram Passport which has the issue.
pub r#type: PassportElementErrorFrontSideType,
/// Base64-encoded hash of the file with the front side of the
/// document.
pub file_hash: String,
}
/// Represents an issue with the reverse side of a document. The error is
/// considered resolved when the file with reverse side of the document
/// changes.
///
/// [The official docs](https://core.telegram.org/bots/api#passportelementerrorreverseside).
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub struct PassportElementErrorReverseSide {
/// The section of the user's Telegram Passport which has the issue.
pub r#type: PassportElementErrorReverseSideType,
//// Base64-encoded hash of the file with the reverse side of the
//// document.
pub file_hash: String,
}
//// Represents an issue with the selfie with a document. The error is
//// considered resolved when the file with the selfie changes.
///
/// [The official docs](https://core.telegram.org/bots/api#passportelementerrorselfie).
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub struct PassportElementErrorSelfie {
/// The section of the user's Telegram Passport which has the issue.
pub r#type: PassportElementErrorSelfieType,
/// Base64-encoded hash of the file with the selfie.
pub file_hash: String,
}
/// Represents an issue with a document scan. The error is considered
/// resolved when the file with the document scan changes.
///
/// [The official docs](https://core.telegram.org/bots/api#passportelementerrorfile).
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub struct PassportElementErrorFile {
/// The section of the user's Telegram Passport which has the issue.
pub r#type: PassportElementErrorFileType,
/// Base64-encoded file hash.
pub file_hash: String,
}
/// Represents an issue with a list of scans. The error is considered
/// resolved when the list of files containing the scans changes.
///
/// [The official docs](https://core.telegram.org/bots/api#passportelementerrorfiles).
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub struct PassportElementErrorFiles {
/// The section of the user's Telegram Passport which has the issue.
pub r#type: PassportElementErrorFilesType,
/// List of base64-encoded file hashes.
pub file_hashes: Vec<String>,
}
/// Represents an issue with one of the files that constitute the
/// translation of a document. The error is considered resolved when the
/// file changes.
///
/// [The official docs](https://core.telegram.org/bots/api#passportelementerrortranslationfile).
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub struct PassportElementErrorTranslationFile {
/// Type of element of the user's Telegram Passport which has the
/// issue.
pub r#type: PassportElementErrorTranslationFileType,
/// Base64-encoded file hash.
pub file_hash: String,
}
/// Represents an issue with the translated version of a document. The
/// error is considered resolved when a file with the document translation
/// change.
///
/// [The official docs](https://core.telegram.org/bots/api#passportelementerrortranslationfiles).
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub struct PassportElementErrorTranslationFiles {
/// Type of element of the user's Telegram Passport which has the issue
pub r#type: PassportElementErrorTranslationFilesType,
/// List of base64-encoded file hashes
pub file_hashes: Vec<String>,
}
/// Represents an issue in an unspecified place. The error is considered
/// resolved when new data is added.
///
/// [The official docs](https://core.telegram.org/bots/api#passportelementerrorunspecified).
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub struct PassportElementErrorUnspecified {
/// Type of element of the user's Telegram Passport which has the
/// issue.
pub r#type: PassportElementErrorUnspecifiedType,
/// Base64-encoded element hash.
pub element_hash: String,
} }
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
@ -252,11 +279,13 @@ mod tests {
fn serialize_data_field() { fn serialize_data_field() {
let data = PassportElementError { let data = PassportElementError {
message: "This is an error message!".to_owned(), message: "This is an error message!".to_owned(),
kind: PassportElementErrorKind::DataField { kind: PassportElementErrorKind::DataField(
r#type: PassportElementErrorDataFieldType::InternalPassport, PassportElementErrorDataField {
field_name: "The field name".to_owned(), r#type: PassportElementErrorDataFieldType::InternalPassport,
data_hash: "This is a data hash".to_owned(), field_name: "The field name".to_owned(),
}, data_hash: "This is a data hash".to_owned(),
},
),
}; };
assert_eq!( assert_eq!(

View file

@ -4,6 +4,7 @@ use serde::{Deserialize, Serialize};
/// This object contains information about a poll. /// This object contains information about a poll.
/// ///
/// [The official docs](https://core.telegram.org/bots/api#poll). /// [The official docs](https://core.telegram.org/bots/api#poll).
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct Poll { pub struct Poll {
/// Unique poll identifier. /// Unique poll identifier.

View file

@ -125,8 +125,9 @@ impl Update {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::types::{ use crate::types::{
Chat, ChatKind, ForwardKind, MediaKind, Message, MessageKind, Update, Chat, ChatKind, ChatPrivate, ForwardKind, ForwardOrigin, MediaKind,
UpdateKind, User, MediaText, Message, MessageCommon, MessageKind, Update, UpdateKind,
User,
}; };
// TODO: more tests for deserialization // TODO: more tests for deserialization
@ -161,15 +162,15 @@ mod test {
date: 1_569_518_342, date: 1_569_518_342,
chat: Chat { chat: Chat {
id: 218_485_655, id: 218_485_655,
kind: ChatKind::Private { kind: ChatKind::Private(ChatPrivate {
type_: (), type_: (),
username: Some(String::from("WaffleLapkin")), username: Some(String::from("WaffleLapkin")),
first_name: Some(String::from("Waffle")), first_name: Some(String::from("Waffle")),
last_name: None, last_name: None,
}, }),
photo: None, photo: None,
}, },
kind: MessageKind::Common { kind: MessageKind::Common(MessageCommon {
from: Some(User { from: Some(User {
id: 218_485_655, id: 218_485_655,
is_bot: false, is_bot: false,
@ -178,16 +179,16 @@ mod test {
username: Some(String::from("WaffleLapkin")), username: Some(String::from("WaffleLapkin")),
language_code: Some(String::from("en")), language_code: Some(String::from("en")),
}), }),
forward_kind: ForwardKind::Origin { forward_kind: ForwardKind::Origin(ForwardOrigin {
reply_to_message: None, reply_to_message: None,
}, }),
edit_date: None, edit_date: None,
media_kind: MediaKind::Text { media_kind: MediaKind::Text(MediaText {
text: String::from("hello there"), text: String::from("hello there"),
entities: vec![], entities: vec![],
}, }),
reply_markup: None, reply_markup: None,
}, }),
}), }),
}; };