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

View file

@ -19,12 +19,27 @@ pub struct EncryptedPassportElement {
pub kind: EncryptedPassportElementKind,
}
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[allow(clippy::large_enum_variant)]
pub enum EncryptedPassportElementKind {
PersonalDetails {
PersonalDetails(EncryptedPassportElementPersonalDetails),
Passport(EncryptedPassportElementPassport),
DriverLicense(EncryptedPassportElementDriverLicense),
IdentityCard(EncryptedPassportElementIdentityCard),
InternalPassport(EncryptedPassportElementInternalPassport),
Address(EncryptedPassportElementAddress),
UtilityBill(EncryptedPassportElementUtilityBill),
BankStatement(EncryptedPassportElementBankStatement),
RentalAgreement(EncryptedPassportElementRentalAgreement),
PassportRegistration(EncryptedPassportElementPassportRegistration),
EncryptedPassportElement(EncryptedPassportElementTemporaryRegistration),
PhoneNumber(EncryptedPassportElementPhoneNumber),
Email(EncryptedPassportElementEmail),
}
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct EncryptedPassportElementPersonalDetails {
/// Base64-encoded encrypted Telegram Passport element data provided
/// by the user, available for `personal_details`, `passport`,
/// `driver_license`, `identity_card`, `internal_passport` and
@ -33,9 +48,12 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
data: String,
},
Passport {
pub data: String,
}
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct EncryptedPassportElementPassport {
/// Base64-encoded encrypted Telegram Passport element data provided
/// by the user, available for `personal_details`, `passport`,
/// `driver_license`, `identity_card`, `internal_passport` and
@ -44,7 +62,7 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
data: String,
pub data: String,
/// Encrypted file with the front side of the document, provided by the
/// user. Available for `passport`, `driver_license`, `identity_card`
@ -53,7 +71,7 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
front_side: PassportFile,
pub front_side: PassportFile,
/// Encrypted file with the selfie of the user holding a document,
/// provided by the user; available for `passport`, `driver_license`,
@ -62,7 +80,7 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
selfie: PassportFile,
pub selfie: PassportFile,
/// Array of encrypted files with translated versions of documents
/// provided by the user. Available if requested for `passport`,
@ -74,9 +92,12 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
translation: Option<Vec<PassportFile>>,
},
DriverLicense {
pub translation: Option<Vec<PassportFile>>,
}
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct EncryptedPassportElementDriverLicense {
/// Base64-encoded encrypted Telegram Passport element data provided
/// by the user, available for `personal_details`, `passport`,
/// `driver_license`, `identity_card`, `internal_passport` and
@ -85,7 +106,7 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
data: String,
pub data: String,
/// Encrypted file with the front side of the document, provided by the
/// user. Available for `passport`, `driver_license`, `identity_card`
@ -94,7 +115,7 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
front_side: PassportFile,
pub front_side: PassportFile,
/// Encrypted file with the reverse side of the document, provided by
/// the user. Available for `driver_license` and `identity_card`. The
@ -103,7 +124,7 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
reverse_side: PassportFile,
pub reverse_side: PassportFile,
/// Encrypted file with the selfie of the user holding a document,
/// provided by the user; available for `passport`, `driver_license`,
@ -112,7 +133,7 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
selfie: PassportFile,
pub selfie: PassportFile,
/// Array of encrypted files with translated versions of documents
/// provided by the user. Available if requested for `passport`,
@ -124,9 +145,12 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
translation: Option<Vec<PassportFile>>,
},
IdentityCard {
pub translation: Option<Vec<PassportFile>>,
}
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct EncryptedPassportElementIdentityCard {
/// Base64-encoded encrypted Telegram Passport element data provided
/// by the user, available for `personal_details`, `passport`,
/// `driver_license`, `identity_card`, `internal_passport` and
@ -135,7 +159,7 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
data: String,
pub data: String,
/// Encrypted file with the front side of the document, provided by the
/// user. Available for `passport`, `driver_license`, `identity_card`
@ -144,7 +168,7 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
front_side: PassportFile,
pub front_side: PassportFile,
/// Encrypted file with the reverse side of the document, provided by
/// the user. Available for `driver_license` and `identity_card`. The
@ -153,7 +177,7 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
reverse_side: PassportFile,
pub reverse_side: PassportFile,
/// Encrypted file with the selfie of the user holding a document,
/// provided by the user; available for `passport`, `driver_license`,
@ -162,7 +186,7 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
selfie: PassportFile,
pub selfie: PassportFile,
/// Array of encrypted files with translated versions of documents
/// provided by the user. Available if requested for `passport`,
@ -174,9 +198,13 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
translation: Option<Vec<PassportFile>>,
},
InternalPassport {
pub translation: Option<Vec<PassportFile>>,
}
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct EncryptedPassportElementInternalPassport {
/// Base64-encoded encrypted Telegram Passport element data provided
/// by the user, available for `personal_details`, `passport`,
/// `driver_license`, `identity_card`, `internal_passport` and
@ -185,7 +213,7 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
data: String,
pub data: String,
/// Encrypted file with the front side of the document, provided by the
/// user. Available for `passport`, `driver_license`, `identity_card`
@ -194,7 +222,7 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
front_side: PassportFile,
pub front_side: PassportFile,
/// Encrypted file with the selfie of the user holding a document,
/// provided by the user; available for `passport`, `driver_license`,
@ -203,7 +231,7 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
selfie: PassportFile,
pub selfie: PassportFile,
/// Array of encrypted files with translated versions of documents
/// provided by the user. Available if requested for `passport`,
@ -215,9 +243,12 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
translation: Option<Vec<PassportFile>>,
},
Address {
pub translation: Option<Vec<PassportFile>>,
}
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct EncryptedPassportElementAddress {
/// Base64-encoded encrypted Telegram Passport element data provided
/// by the user, available for `personal_details`, `passport`,
/// `driver_license`, `identity_card`, `internal_passport` and
@ -226,9 +257,12 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
data: String,
},
UtilityBill {
pub data: String,
}
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct EncryptedPassportElementUtilityBill {
/// 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
@ -237,7 +271,7 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
files: Vec<PassportFile>,
pub files: Vec<PassportFile>,
/// Array of encrypted files with translated versions of documents
/// provided by the user. Available if requested for `passport`,
@ -249,9 +283,13 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
translation: Option<Vec<PassportFile>>,
},
BankStatement {
pub translation: Option<Vec<PassportFile>>,
}
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct EncryptedPassportElementBankStatement {
/// 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
@ -260,7 +298,7 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
files: Vec<PassportFile>,
pub files: Vec<PassportFile>,
/// Array of encrypted files with translated versions of documents
/// provided by the user. Available if requested for `passport`,
@ -272,9 +310,12 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
translation: Option<Vec<PassportFile>>,
},
RentalAgreement {
pub translation: Option<Vec<PassportFile>>,
}
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct EncryptedPassportElementRentalAgreement {
/// 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
@ -283,7 +324,7 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
files: Vec<PassportFile>,
pub files: Vec<PassportFile>,
/// Array of encrypted files with translated versions of documents
/// provided by the user. Available if requested for `passport`,
@ -295,9 +336,13 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
translation: Option<Vec<PassportFile>>,
},
PassportRegistration {
pub translation: Option<Vec<PassportFile>>,
}
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct EncryptedPassportElementPassportRegistration {
/// 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
@ -306,7 +351,7 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
files: Vec<PassportFile>,
pub files: Vec<PassportFile>,
/// Array of encrypted files with translated versions of documents
/// provided by the user. Available if requested for `passport`,
@ -318,9 +363,12 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
translation: Option<Vec<PassportFile>>,
},
TemporaryRegistration {
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
@ -329,7 +377,7 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
files: Vec<PassportFile>,
pub files: Vec<PassportFile>,
/// Array of encrypted files with translated versions of documents
/// provided by the user. Available if requested for `passport`,
@ -341,15 +389,21 @@ pub enum EncryptedPassportElementKind {
///
/// [`EncryptedCredentials`]:
/// crate::types::EncryptedCredentials
translation: Option<Vec<PassportFile>>,
},
PhoneNumber {
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.
phone_number: String,
},
Email {
/// User's verified email address, available only for `email` type.
email: String,
},
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::{
inline_keyboard_markup::InlineKeyboardMarkup, parse_mode::ParseMode,
InlineQueryResult, InlineQueryResultCachedAudio, InputMessageContent,
InputMessageContentText,
};
#[test]
@ -89,11 +90,13 @@ mod tests {
caption: Some(String::from("caption")),
parse_mode: Some(ParseMode::HTML),
reply_markup: Some(InlineKeyboardMarkup::default()),
input_message_content: Some(InputMessageContent::Text {
input_message_content: Some(InputMessageContent::Text(
InputMessageContentText {
message_text: String::from("message_text"),
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}}"#;

View file

@ -3,7 +3,6 @@ use serde::{Deserialize, Serialize};
use crate::types::{InputFile, ParseMode};
// TODO: should variants use new-type?
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type")]
#[serde(rename_all = "snake_case")]
@ -11,15 +10,24 @@ use crate::types::{InputFile, ParseMode};
///
/// [The official docs](https://core.telegram.org/bots/api#inputmedia).
pub enum InputMedia {
/// Represents a photo to be sent.
///
/// [The official docs](https://core.telegram.org/bots/api#inputmediaphoto).
Photo {
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.
media: InputFile,
pub media: InputFile,
/// Caption of the photo to be sent, 0-1024 characters.
caption: Option<String>,
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.
@ -27,25 +35,27 @@ pub enum InputMedia {
/// [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>,
},
pub parse_mode: Option<ParseMode>,
}
/// Represents a video to be sent.
///
/// [The official docs](https://core.telegram.org/bots/api#inputmediavideo).
Video {
/// Represents a video to be sent.
///
/// [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.
media: InputFile,
pub media: InputFile,
/// 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>,
pub thumb: Option<InputFile>,
/// Caption of the video to be sent, 0-1024 characters.
caption: Option<String>,
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.
@ -53,38 +63,40 @@ pub enum InputMedia {
/// [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>,
pub parse_mode: Option<ParseMode>,
/// Video width.
width: Option<u16>,
pub width: Option<u16>,
/// Video height.
height: Option<u16>,
pub height: Option<u16>,
/// Video duration.
duration: Option<u16>,
pub duration: Option<u16>,
/// Pass `true`, if the uploaded video is suitable for streaming.
supports_streaming: Option<bool>,
},
pub supports_streaming: Option<bool>,
}
/// Represents an animation file (GIF or H.264/MPEG-4 AVC video without
/// sound) to be sent.
///
/// [The official docs](https://core.telegram.org/bots/api#inputmediaanimation).
Animation {
/// Represents an animation file (GIF or H.264/MPEG-4 AVC video without
/// 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.
media: InputFile,
pub media: InputFile,
/// 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>,
pub thumb: Option<InputFile>,
/// Caption of the animation to be sent, 0-1024 characters.
caption: Option<String>,
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.
@ -92,34 +104,36 @@ pub enum InputMedia {
/// [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>,
pub parse_mode: Option<ParseMode>,
/// Animation width.
width: Option<u16>,
pub width: Option<u16>,
/// Animation height.
height: Option<u16>,
pub height: Option<u16>,
/// Animation duration.
duration: Option<u16>,
},
pub duration: Option<u16>,
}
/// Represents an audio file to be treated as music to be sent.
///
/// [The official docs](https://core.telegram.org/bots/api#inputmediaaudio).
Audio {
/// Represents an audio file to be treated as music to be sent.
///
/// [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.
media: InputFile,
pub media: InputFile,
/// 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>,
pub thumb: Option<InputFile>,
/// Caption of the audio to be sent, 0-1024 characters.
caption: Option<String>,
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.
@ -127,34 +141,36 @@ pub enum InputMedia {
/// [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>,
pub parse_mode: Option<String>,
/// Duration of the audio in seconds.
duration: Option<u16>,
pub duration: Option<u16>,
/// Performer of the audio.
performer: Option<String>,
pub performer: Option<String>,
/// Title of the audio.
title: Option<String>,
},
pub title: Option<String>,
}
/// Represents a general file to be sent.
///
/// [The official docs](https://core.telegram.org/bots/api#inputmediadocument).
Document {
/// Represents a general file to be sent.
///
/// [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.
media: InputFile,
pub media: InputFile,
/// 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>,
pub thumb: Option<InputFile>,
/// Caption of the document to be sent, 0-1024 charactersю
caption: Option<String>,
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.
@ -162,18 +178,17 @@ pub enum InputMedia {
/// [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>,
},
pub parse_mode: Option<ParseMode>,
}
impl InputMedia {
pub fn media(&self) -> &InputFile {
match self {
InputMedia::Photo { media, .. }
| InputMedia::Document { media, .. }
| InputMedia::Audio { media, .. }
| InputMedia::Animation { media, .. }
| InputMedia::Video { media, .. } => media,
InputMedia::Photo(InputMediaPhoto { media, .. })
| InputMedia::Document(InputMediaDocument { media, .. })
| InputMedia::Audio(InputMediaAudio { media, .. })
| InputMedia::Animation(InputMediaAnimation { media, .. })
| InputMedia::Video(InputMediaVideo { media, .. }) => media,
}
}
}
@ -181,11 +196,11 @@ impl InputMedia {
impl From<InputMedia> for InputFile {
fn from(media: InputMedia) -> InputFile {
match media {
InputMedia::Photo { media, .. }
| InputMedia::Document { media, .. }
| InputMedia::Audio { media, .. }
| InputMedia::Animation { media, .. }
| InputMedia::Video { media, .. } => media,
InputMedia::Photo(InputMediaPhoto { media, .. })
| InputMedia::Document(InputMediaDocument { media, .. })
| InputMedia::Audio(InputMediaAudio { media, .. })
| InputMedia::Animation(InputMediaAnimation { media, .. })
| InputMedia::Video(InputMediaVideo { media, .. }) => media,
}
}
}
@ -197,11 +212,11 @@ mod tests {
#[test]
fn photo_serialize() {
let expected_json = r#"{"type":"photo","media":"123456"}"#;
let photo = InputMedia::Photo {
let photo = InputMedia::Photo(InputMediaPhoto {
media: InputFile::FileId(String::from("123456")),
caption: None,
parse_mode: None,
};
});
let actual_json = serde_json::to_string(&photo).unwrap();
assert_eq!(expected_json, actual_json);
@ -210,7 +225,7 @@ mod tests {
#[test]
fn video_serialize() {
let expected_json = r#"{"type":"video","media":"123456"}"#;
let video = InputMedia::Video {
let video = InputMedia::Video(InputMediaVideo {
media: InputFile::FileId(String::from("123456")),
thumb: None,
caption: None,
@ -219,7 +234,7 @@ mod tests {
height: None,
duration: None,
supports_streaming: None,
};
});
let actual_json = serde_json::to_string(&video).unwrap();
assert_eq!(expected_json, actual_json);
@ -228,7 +243,7 @@ mod tests {
#[test]
fn animation_serialize() {
let expected_json = r#"{"type":"animation","media":"123456"}"#;
let video = InputMedia::Animation {
let video = InputMedia::Animation(InputMediaAnimation {
media: InputFile::FileId(String::from("123456")),
thumb: None,
caption: None,
@ -236,7 +251,7 @@ mod tests {
width: None,
height: None,
duration: None,
};
});
let actual_json = serde_json::to_string(&video).unwrap();
assert_eq!(expected_json, actual_json);
@ -245,7 +260,7 @@ mod tests {
#[test]
fn audio_serialize() {
let expected_json = r#"{"type":"audio","media":"123456"}"#;
let video = InputMedia::Audio {
let video = InputMedia::Audio(InputMediaAudio {
media: InputFile::FileId(String::from("123456")),
thumb: None,
caption: None,
@ -253,7 +268,7 @@ mod tests {
duration: None,
performer: None,
title: None,
};
});
let actual_json = serde_json::to_string(&video).unwrap();
assert_eq!(expected_json, actual_json);
@ -262,12 +277,12 @@ mod tests {
#[test]
fn document_serialize() {
let expected_json = r#"{"type":"document","media":"123456"}"#;
let video = InputMedia::Document {
let video = InputMedia::Document(InputMediaDocument {
media: InputFile::FileId(String::from("123456")),
thumb: None,
caption: None,
parse_mode: None,
};
});
let actual_json = serde_json::to_string(&video).unwrap();
assert_eq!(expected_json, actual_json);

View file

@ -2,19 +2,25 @@ use serde::{Deserialize, Serialize};
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
/// inline query.
///
/// [The official docs](https://core.telegram.org/bots/api#inputmessagecontent).
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum InputMessageContent {
/// Represents the content of a text message to be sent as the result of an
/// inline query.
Text {
Text(InputMessageContentText),
Location(InputMessageContentLocation),
Venue(InputMessageContentVenue),
Contact(InputMessageContentContact),
}
/// 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.
message_text: String,
pub message_text: String,
/// Send [Markdown] or [HTML], if you want Telegram apps to show [bold,
/// italic, fixed-width text or inline URLs] in the media caption.
@ -22,68 +28,74 @@ pub enum InputMessageContent {
/// [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>,
pub parse_mode: Option<ParseMode>,
/// 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
/// of an inline query.
Location {
/// Represents the content of a location 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 InputMessageContentLocation {
/// Latitude of the location in degrees.
latitude: f64,
pub latitude: f64,
/// Longitude of the location in degrees.
longitude: f64,
pub longitude: f64,
/// Period in seconds for which the location can be updated, should be
/// 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
/// an inline query.
Venue {
/// Represents the content of a venue 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 InputMessageContentVenue {
/// Latitude of the venue in degrees.
latitude: f64,
pub latitude: f64,
/// Longitude of the venue in degrees.
longitude: f64,
pub longitude: f64,
/// Name of the venue.
title: String,
pub title: String,
/// Address of the venue.
address: String,
pub address: String,
/// Foursquare identifier of the venue, if known.
foursquare_id: Option<String>,
pub foursquare_id: Option<String>,
/// Foursquare type of the venue, if known. (For example,
/// `arts_entertainment/default`, `arts_entertainment/aquarium`
/// or `food/icecream`.)
foursquare_type: Option<String>,
},
pub foursquare_type: Option<String>,
}
/// Represents the content of a contact message to be sent as the result of
/// an inline query.
Contact {
/// Represents the content of a contact 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 InputMessageContentContact {
/// Contact's phone number.
phone_number: String,
pub phone_number: String,
/// Contact's first name.
first_name: String,
pub first_name: String,
/// Contact's last name.
last_name: Option<String>,
pub last_name: Option<String>,
/// Additional data about the contact in the form of a [vCard], 0-2048
/// bytes.
///
/// [vCard]: https://en.wikipedia.org/wiki/VCard
vcard: Option<String>,
},
pub vcard: Option<String>,
}
#[cfg(test)]
@ -93,11 +105,11 @@ mod tests {
#[test]
fn text_serialize() {
let expected_json = r#"{"message_text":"text"}"#;
let text_content = InputMessageContent::Text {
let text_content = InputMessageContent::Text(InputMessageContentText {
message_text: String::from("text"),
parse_mode: None,
disable_web_page_preview: None,
};
});
let actual_json = serde_json::to_string(&text_content).unwrap();
assert_eq!(expected_json, actual_json);
@ -106,11 +118,12 @@ mod tests {
#[test]
fn location_serialize() {
let expected_json = r#"{"latitude":59.08,"longitude":38.4326}"#;
let location_content = InputMessageContent::Location {
let location_content =
InputMessageContent::Location(InputMessageContentLocation {
latitude: 59.08,
longitude: 38.4326,
live_period: None,
};
});
let actual_json = serde_json::to_string(&location_content).unwrap();
assert_eq!(expected_json, actual_json);
@ -119,14 +132,15 @@ mod tests {
#[test]
fn venue_serialize() {
let expected_json = r#"{"latitude":59.08,"longitude":38.4326,"title":"some title","address":"some address"}"#;
let venue_content = InputMessageContent::Venue {
let venue_content =
InputMessageContent::Venue(InputMessageContentVenue {
latitude: 59.08,
longitude: 38.4326,
title: String::from("some title"),
address: String::from("some address"),
foursquare_id: None,
foursquare_type: None,
};
});
let actual_json = serde_json::to_string(&venue_content).unwrap();
assert_eq!(expected_json, actual_json);
@ -136,12 +150,13 @@ mod tests {
fn contact_serialize() {
let expected_json =
r#"{"phone_number":"+3800000000","first_name":"jhon"}"#;
let contact_content = InputMessageContent::Contact {
let contact_content =
InputMessageContent::Contact(InputMessageContentContact {
phone_number: String::from("+3800000000"),
first_name: String::from("jhon"),
last_name: None,
vcard: None,
};
});
let actual_json = serde_json::to_string(&contact_content).unwrap();
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)]
mod tests {
use super::*;
use crate::types::{Chat, ChatKind, ForwardKind, MediaKind, MessageKind};
use crate::types::{
Chat, ChatKind, ChatPrivate, ForwardKind, ForwardOrigin, MediaKind,
MediaText, MessageCommon, MessageKind,
};
#[test]
fn recursive_kind() {
@ -103,15 +106,15 @@ mod tests {
date: 0,
chat: Chat {
id: 0,
kind: ChatKind::Private {
kind: ChatKind::Private(ChatPrivate {
type_: (),
username: None,
first_name: None,
last_name: None,
},
}),
photo: None,
},
kind: MessageKind::Common {
kind: MessageKind::Common(MessageCommon {
from: Some(User {
id: 0,
is_bot: false,
@ -120,18 +123,20 @@ mod tests {
username: None,
language_code: None,
}),
forward_kind: ForwardKind::Origin { reply_to_message: None },
forward_kind: ForwardKind::Origin(ForwardOrigin {
reply_to_message: None,
}),
edit_date: None,
media_kind: MediaKind::Text {
media_kind: MediaKind::Text(MediaText {
text: "no yes no".to_string(),
entities: vec![MessageEntity {
kind: MessageEntityKind::Mention,
offset: 3,
length: 3,
}],
},
}),
reply_markup: None,
},
}),
}
}
}

View file

@ -17,133 +17,160 @@ pub struct PassportElementError {
#[serde(tag = "source")]
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
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")]
DataField {
DataField(PassportElementErrorDataField),
#[serde(rename = "snake_case")]
FrontSide(PassportElementErrorFrontSide),
#[serde(rename = "snake_case")]
ReverseSide(PassportElementErrorReverseSide),
#[serde(rename = "snake_case")]
Selfie(PassportElementErrorSelfie),
#[serde(rename = "snake_case")]
File(PassportElementErrorFile),
#[serde(rename = "snake_case")]
Files(PassportElementErrorFiles),
#[serde(rename = "snake_case")]
TranslationFile(PassportElementErrorTranslationFile),
#[serde(rename = "snake_case")]
TranslationFiles(PassportElementErrorTranslationFiles),
#[serde(rename = "snake_case")]
Unspecified(PassportElementErrorUnspecified),
}
/// 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).
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub struct PassportElementErrorDataField {
/// The section of the user's Telegram Passport which has the error.
r#type: PassportElementErrorDataFieldType,
pub r#type: PassportElementErrorDataFieldType,
/// Name of the data field which has the error.
field_name: String,
pub field_name: String,
/// Base64-encoded data hash.
data_hash: String,
},
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).
#[serde(rename = "snake_case")]
FrontSide {
/// 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.
r#type: PassportElementErrorFrontSideType,
pub r#type: PassportElementErrorFrontSideType,
/// Base64-encoded hash of the file with the front side of the
/// document.
file_hash: String,
},
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).
#[serde(rename = "snake_case")]
ReverseSide {
/// 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.
r#type: PassportElementErrorReverseSideType,
pub r#type: PassportElementErrorReverseSideType,
//// Base64-encoded hash of the file with the reverse side of the
//// document.
file_hash: String,
},
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).
#[serde(rename = "snake_case")]
Selfie {
//// 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.
r#type: PassportElementErrorSelfieType,
pub r#type: PassportElementErrorSelfieType,
/// Base64-encoded hash of the file with the selfie.
file_hash: String,
},
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).
#[serde(rename = "snake_case")]
File {
/// 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.
r#type: PassportElementErrorFileType,
pub r#type: PassportElementErrorFileType,
/// Base64-encoded file hash.
file_hash: String,
},
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).
#[serde(rename = "snake_case")]
Files {
/// 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.
r#type: PassportElementErrorFilesType,
pub r#type: PassportElementErrorFilesType,
/// List of base64-encoded file hashes.
file_hashes: Vec<String>,
},
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).
#[serde(rename = "snake_case")]
TranslationFile {
/// 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.
r#type: PassportElementErrorTranslationFileType,
pub r#type: PassportElementErrorTranslationFileType,
/// Base64-encoded file hash.
file_hash: String,
},
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).
#[serde(rename = "snake_case")]
TranslationFiles {
/// 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
r#type: PassportElementErrorTranslationFilesType,
pub r#type: PassportElementErrorTranslationFilesType,
/// List of base64-encoded file hashes
file_hashes: Vec<String>,
},
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).
#[serde(rename = "snake_case")]
Unspecified {
/// 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.
r#type: PassportElementErrorUnspecifiedType,
pub r#type: PassportElementErrorUnspecifiedType,
/// Base64-encoded element hash.
element_hash: String,
},
pub element_hash: String,
}
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
@ -252,11 +279,13 @@ mod tests {
fn serialize_data_field() {
let data = PassportElementError {
message: "This is an error message!".to_owned(),
kind: PassportElementErrorKind::DataField {
kind: PassportElementErrorKind::DataField(
PassportElementErrorDataField {
r#type: PassportElementErrorDataFieldType::InternalPassport,
field_name: "The field name".to_owned(),
data_hash: "This is a data hash".to_owned(),
},
),
};
assert_eq!(

View file

@ -4,6 +4,7 @@ use serde::{Deserialize, Serialize};
/// This object contains information about a 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)]
pub struct Poll {
/// Unique poll identifier.

View file

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