use super::games::CallbackGame;
use super::inline_mode::{ChosenInlineResult, InlineQuery};
use super::utils::falsum;
#[cfg(feature = "high")]
use chrono::naive::NaiveDateTime;
macro_rules! impl_id {
($Id: ident : $Ty: ty) => {
#[derive(
Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
)]
pub struct $Id(pub $Ty);
impl ::std::ops::Add<$Ty> for $Id {
type Output = $Id;
#[inline]
fn add(self, other: $Ty) -> $Id {
$Id(self.0 + other)
}
}
impl<'a> ::std::ops::Add<&'a $Ty> for $Id {
type Output = $Id;
#[inline]
fn add(self, other: &$Ty) -> Self::Output {
$Id(self.0 + other)
}
}
impl ::std::ops::Sub<$Ty> for $Id {
type Output = $Id;
#[inline]
fn sub(self, other: $Ty) -> $Id {
$Id(self.0 - other)
}
}
impl ::std::ops::AddAssign<$Ty> for $Id {
fn add_assign(&mut self, rhs: $Ty) {
self.0 += rhs
}
}
impl ::std::ops::SubAssign<$Ty> for $Id {
fn sub_assign(&mut self, rhs: $Ty) {
self.0 -= rhs
}
}
};
}
impl_id! {UserId : i64}
impl_id! {ChatId : i64}
impl_id! {MessageId : i64}
impl_id! {UpdateId : i64}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct FileId(pub String);
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MessageIdResult {
pub message_id: MessageId,
}
#[cfg(not(feature = "high"))]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Time(pub u64);
#[cfg(feature = "high")]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Time(#[serde(with = "timestamp_format")] pub NaiveDateTime);
#[cfg(feature = "high")]
mod timestamp_format {
use chrono::naive::NaiveDateTime;
use serde::{Deserialize, Deserializer, Serializer};
pub fn serialize<S>(date: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_i64(date.timestamp())
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<NaiveDateTime, D::Error>
where
D: Deserializer<'de>,
{
let s = i64::deserialize(deserializer)?;
Ok(NaiveDateTime::from_timestamp(s, 0))
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Update {
pub update_id: UpdateId,
#[serde(flatten)]
pub content: Option<UpdateContent>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum UpdateContent {
Message(Message),
EditedMessage(Message),
ChannelPost(Message),
EditedChannelPost(Message),
InlineQuery(InlineQuery),
ChosenInlineResult(ChosenInlineResult),
CallbackQuery(CallbackQuery),
MyChatMember(ChatMemberUpdated),
ChatMember(ChatMemberUpdated),
ChatJoinRequest(ChatJoinRequest),
#[doc(hidden)]
ShippingQuery(ShippingQuery),
#[doc(hidden)]
PreCheckoutQuery(PreCheckoutQuery),
#[doc(hidden)]
Poll(Poll),
#[doc(hidden)]
PollAnswer(PollAnswer),
Unknown,
}
impl Default for UpdateContent {
fn default() -> Self {
UpdateContent::Unknown {}
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ShippingQuery {}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct PreCheckoutQuery {}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Poll {}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct PollAnswer {}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ChatMemberUpdated {
pub chat: Chat,
pub from: User,
pub date: Time,
pub old_chat_member: ChatMember,
pub new_chat_member: ChatMember,
pub invite_link: Option<ChatInviteLink>,
pub via_join_request: Option<bool>,
pub via_chat_folder_invite_link: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ChatJoinRequest {
pub chat: Chat,
pub from: User,
pub user_chat_id: UserId,
pub date: Time,
pub bio: Option<String>,
pub invite_link: Option<ChatInviteLink>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ChatInviteLink {
invite_link: String,
creator: User,
creates_join_request: bool,
is_primary: bool,
is_revoked: bool,
name: Option<String>,
expire_date: Option<Time>,
member_limit: Option<i32>,
pending_join_request_count: Option<i32>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct WebhookInfo {
pub url: String,
pub has_custom_certificate: bool,
pub pending_update_count: i32,
pub ip_address: Option<String>,
pub last_error_date: Option<Time>,
pub last_error_message: Option<String>,
pub max_connections: Option<i32>,
pub allowed_updates: Option<Vec<String>>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct User {
pub id: UserId,
pub is_bot: bool,
pub first_name: String,
pub last_name: Option<String>,
pub username: Option<String>,
pub language_code: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(tag = "type")]
#[serde(rename_all = "snake_case")]
pub enum ChatType {
Private {
username: Option<String>,
first_name: String,
last_name: Option<String>,
},
Group {
title: String,
username: Option<String>,
#[serde(default = "falsum")]
all_members_are_administrators: bool,
},
Supergroup {
title: String,
username: Option<String>,
#[serde(default = "falsum")]
all_members_are_administrators: bool,
pinned_message: Option<Box<Message>>,
sticker_set_name: Option<String>,
can_set_sticker_set: Option<bool>,
invite_link: Option<String>,
description: Option<String>,
},
Channel {
title: String,
username: Option<String>,
pinned_message: Option<Box<Message>>,
invite_link: Option<String>,
description: Option<String>,
},
#[serde(other)]
Unknown,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Chat {
pub id: ChatId,
pub photo: Option<ChatPhoto>,
#[serde(flatten)]
#[serde(rename = "type")]
pub kind: ChatType,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Message {
pub message_id: MessageId,
pub from: Option<Box<User>>,
pub sender_chat: Option<Chat>,
pub date: Time,
pub chat: Box<Chat>,
pub forward_from: Option<Box<User>>,
pub forward_from_chat: Option<Box<Chat>>,
pub forward_from_message_id: Option<MessageId>,
pub forward_signature: Option<String>,
pub forward_sender_name: Option<String>,
pub forward_date: Option<Time>,
pub reply_to_message: Option<Box<Message>>,
pub edit_date: Option<Time>,
pub media_group_id: Option<String>,
pub author_signature: Option<String>,
pub text: Option<String>,
pub sticker: Option<Box<Sticker>>,
pub audio: Option<Audio>,
pub document: Option<Box<Document>>,
#[serde(default)]
pub photo: Vec<PhotoSize>,
#[serde(default)]
pub entities: Vec<MessageEntity>,
pub voice: Option<Box<Voice>>,
pub video: Option<Video>,
pub video_note: Option<Box<VideoNote>>,
pub animation: Option<Box<Animation>>,
#[serde(default)]
pub caption_entities: Vec<MessageEntity>,
pub caption: Option<String>,
pub contact: Option<Box<Contact>>,
pub location: Option<Box<Location>>,
pub venue: Option<Box<Venue>>,
#[serde(default)]
pub new_chat_members: Vec<User>,
pub left_chat_member: Option<Box<User>>,
pub new_chat_title: Option<String>,
#[serde(default)]
pub new_chat_photo: Vec<PhotoSize>,
#[serde(default = "falsum")]
pub delete_chat_photo: bool,
#[serde(default = "falsum")]
pub group_chat_created: bool,
#[serde(default = "falsum")]
pub supergroup_chat_created: bool,
#[serde(default = "falsum")]
pub channel_chat_created: bool,
pub migrate_to_chat_id: Option<ChatId>,
pub migrate_from_chat_id: Option<ChatId>,
pub pinned_message: Option<Box<Message>>,
pub connected_website: Option<String>,
pub reply_markup: Option<InlineKeyboardMarkup>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct MessageEntity {
#[serde(rename = "type")]
pub kind: MessageEntityKind,
pub offset: i32,
pub length: i32,
pub url: Option<String>,
pub user: Option<Box<User>>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[serde(rename_all = "snake_case")]
pub enum MessageEntityKind {
Mention,
Hashtag,
Cashtag,
BotCommand,
Url,
Email,
PhoneNumber,
Bold,
Italic,
Code,
Pre,
TextLink,
TextMention,
#[serde(other)]
Unknown,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Hash, Eq)]
pub struct Document {
pub file_id: FileId,
pub thumb: Option<PhotoSize>,
pub file_name: Option<String>,
pub mime_type: Option<String>,
pub file_size: Option<i32>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Hash, Eq)]
pub struct Video {
pub file_id: FileId,
pub width: i32,
pub height: i32,
pub duration: i32,
pub thumb: Option<PhotoSize>,
pub mime_type: Option<String>,
pub file_size: Option<i32>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Hash, Eq)]
pub struct Animation {
pub file_id: FileId,
pub width: i32,
pub height: i32,
pub duration: i32,
pub thumb: Option<PhotoSize>,
pub file_name: Option<String>,
pub mime_type: Option<String>,
pub file_size: Option<i32>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Hash, Eq)]
pub struct Audio {
pub file_id: FileId,
pub duration: i32,
pub performer: Option<String>,
pub title: Option<String>,
pub mime_type: Option<String>,
pub file_size: Option<i32>,
pub thumb: Option<PhotoSize>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Voice {
pub file_id: FileId,
pub duration: i32,
pub mime_type: Option<String>,
pub file_size: Option<i32>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct VideoNote {
pub file_id: FileId,
pub length: i32,
pub duration: i32,
pub thumb: Option<PhotoSize>,
pub file_size: Option<i32>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct Contact {
pub phone_number: String,
pub first_name: String,
pub last_name: Option<String>,
pub user_id: Option<UserId>,
pub vcard: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Hash)]
pub struct File {
pub file_id: FileId,
pub file_size: Option<i32>,
pub file_path: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, PartialOrd)]
pub struct Location {
pub longitude: f32,
pub latitude: f32,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, PartialOrd)]
pub struct Venue {
pub location: Location,
pub title: String,
pub address: String,
pub foursquare_id: Option<String>,
pub foursquare_type: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
pub struct PhotoSize {
pub file_id: FileId,
pub width: i32,
pub height: i32,
pub file_size: Option<i32>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct UserProfilePhotos {
pub total_count: i32,
#[serde(default)]
pub photos: Vec<PhotoSize>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct ReplyKeyboardMarkup {
#[serde(default)]
pub keyboard: Vec<Vec<KeyboardButton>>,
pub resize_keyboard: Option<bool>,
pub one_time_keyboard: Option<bool>,
pub selective: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct KeyboardButton {
pub text: String,
pub request_contact: Option<bool>,
pub request_location: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct ReplyKeyboardRemove {
pub remove_keyboard: bool,
pub selective: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct InlineKeyboardMarkup {
#[serde(default)]
pub inline_keyboard: Vec<Vec<InlineKeyboardButton>>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct InlineKeyboardButton {
pub text: String,
#[serde(flatten)]
pub pressed: InlineKeyboardButtonPressed,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum InlineKeyboardButtonPressed {
Url(String),
CallbackData(String),
SwitchInlineQuery(String),
SwitchInlineQueryCurrentChat(String),
Pay(bool),
CallbackGame(CallbackGame),
LoginUrl(LoginUrl),
#[serde(other)]
Unknown,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct CallbackQuery {
pub id: String,
pub from: Box<User>,
pub message: Option<Box<Message>>,
pub inline_message_id: Option<String>,
pub chat_instance: String,
pub data: Option<String>,
pub game_short_name: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct ForceReply {
pub force_reply: bool,
pub selective: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct ResponseParameters {
pub migrate_to_chat_id: Option<ChatId>,
pub retry_after: Option<i32>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct ChatPhoto {
pub small_file_id: FileId,
pub big_file_id: FileId,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct ChatMember {
pub user: Box<User>,
pub status: ChatMemberStatus,
pub until_date: Option<Time>,
pub can_be_edited: Option<bool>,
pub can_change_info: Option<bool>,
pub can_post_messages: Option<bool>,
pub can_edit_messages: Option<bool>,
pub can_delete_messages: Option<bool>,
pub can_invite_users: Option<bool>,
pub can_restrict_members: Option<bool>,
pub can_pin_messages: Option<bool>,
pub can_promote_members: Option<bool>,
pub is_member: Option<bool>,
pub can_send_messages: Option<bool>,
pub can_send_media_messages: Option<bool>,
pub can_send_other_messages: Option<bool>,
pub can_add_web_page_previews: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[serde(rename_all = "lowercase")]
pub enum ChatMemberStatus {
Creator,
Administrator,
Member,
Restricted,
Left,
Kicked,
#[serde(other)]
Unknown,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct InputFile(pub String);
impl InputFile {
pub fn new<S: AsRef<str>>(file_attach_name: S) -> InputFile {
let attach = format!("attach://{}", file_attach_name.as_ref());
InputFile(attach)
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[serde(untagged)]
pub enum FileToSend {
FileId(FileId),
Url(String),
InputFile(InputFile),
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Sticker {
pub file_id: FileId,
pub width: i32,
pub height: i32,
pub thumb: Option<PhotoSize>,
pub emoji: Option<String>,
pub set_name: Option<String>,
pub mask_position: Option<MaskPosition>,
pub file_size: i32,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct StickerSet {
pub name: String,
pub title: String,
pub contains_masks: bool,
#[serde(default)]
pub stickers: Vec<Sticker>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct MaskPosition {
pub point: String,
pub x_shift: f32,
pub y_shift: f32,
pub scale: f32,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
#[serde(tag = "type")]
pub enum InputMedia {
#[serde(rename = "video")]
Video {
media: FileToSend,
#[serde(skip_serializing_if = "Option::is_none")]
caption: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
parse_mode: Option<ParseMode>,
#[serde(skip_serializing_if = "Option::is_none")]
width: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
height: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
duration: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
supports_streaming: Option<bool>,
},
#[serde(rename = "photo")]
Photo {
media: FileToSend,
#[serde(skip_serializing_if = "Option::is_none")]
caption: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
parse_mode: Option<ParseMode>,
},
#[serde(rename = "animation")]
Animation {
media: FileToSend,
#[serde(skip_serializing_if = "Option::is_none")]
thumb: Option<InputFile>,
#[serde(skip_serializing_if = "Option::is_none")]
caption: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
parse_mode: Option<ParseMode>,
#[serde(skip_serializing_if = "Option::is_none")]
width: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
height: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
duration: Option<i32>,
},
#[serde(rename = "audio")]
Audio {
media: FileToSend,
#[serde(skip_serializing_if = "Option::is_none")]
thumb: Option<InputFile>,
#[serde(skip_serializing_if = "Option::is_none")]
caption: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
parse_mode: Option<ParseMode>,
#[serde(skip_serializing_if = "Option::is_none")]
duration: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
performer: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
title: Option<String>,
},
#[serde(rename = "document")]
Document {
media: FileToSend,
#[serde(skip_serializing_if = "Option::is_none")]
thumb: Option<InputFile>,
#[serde(skip_serializing_if = "Option::is_none")]
caption: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
parse_mode: Option<ParseMode>,
},
#[serde(other)]
Unknown,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct LoginUrl {
pub url: String,
pub forward_text: Option<String>,
pub bot_username: Option<String>,
pub request_write_access: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub enum ParseMode {
Markdown,
MarkdownV2,
HTML,
#[serde(other)]
Unknown,
}