From 1b9092c7042e8cfdfc2734ce57c17ea85e3e2f2f Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sun, 25 Sep 2022 21:56:28 +0400 Subject: [PATCH 1/5] Start using `MessageId` in APIs --- src/types/message.rs | 22 +++++++++++++--------- src/types/message_id.rs | 24 ++++++++++++++++++++---- src/types/target_message.rs | 12 +++++++++--- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/src/types/message.rs b/src/types/message.rs index d42835ae..54da04d9 100644 --- a/src/types/message.rs +++ b/src/types/message.rs @@ -7,7 +7,7 @@ use url::Url; use crate::types::{ Animation, Audio, BareChatId, Chat, ChatId, Contact, Dice, Document, Game, InlineKeyboardMarkup, Invoice, Location, MessageAutoDeleteTimerChanged, MessageEntity, - MessageEntityRef, PassportData, PhotoSize, Poll, ProximityAlertTriggered, Sticker, + MessageEntityRef, MessageId, PassportData, PhotoSize, Poll, ProximityAlertTriggered, Sticker, SuccessfulPayment, True, User, Venue, Video, VideoChatEnded, VideoChatParticipantsInvited, VideoChatScheduled, VideoChatStarted, VideoNote, Voice, WebAppData, }; @@ -18,8 +18,8 @@ use crate::types::{ #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct Message { /// Unique message identifier inside this chat. - #[serde(rename = "message_id")] - pub id: i32, + #[serde(flatten)] + pub id: MessageId, /// Date the message was sent in Unix time. #[serde(with = "crate::types::serde_date_from_unix_timestamp")] @@ -1158,7 +1158,11 @@ impl Message { /// [`url`]: Message::url #[track_caller] #[must_use] - pub fn url_of(chat_id: ChatId, chat_username: Option<&str>, message_id: i32) -> Option { + pub fn url_of( + chat_id: ChatId, + chat_username: Option<&str>, + message_id: MessageId, + ) -> Option { use BareChatId::*; // Note: `t.me` links use bare chat ids @@ -1181,10 +1185,10 @@ impl Message { let url = match chat_username { // If it's public group (i.e. not DM, not private group), we can produce // "normal" t.me link (accessible to everyone). - Some(username) => format!("https://t.me/{0}/{1}", username, message_id), + Some(username) => format!("https://t.me/{0}/{1}", username, message_id.0), // For private supergroups and channels we produce "private" t.me/c links. These are // only accessible to the group members. - None => format!("https://t.me/c/{0}/{1}", chat_id, message_id), + None => format!("https://t.me/c/{0}/{1}", chat_id, message_id.0), }; // UNWRAP: @@ -1276,11 +1280,11 @@ impl Message { pub fn url_in_thread_of( chat_id: ChatId, chat_username: Option<&str>, - thread_starter_msg_id: i32, - message_id: i32, + thread_starter_msg_id: MessageId, + message_id: MessageId, ) -> Option { Self::url_of(chat_id, chat_username, message_id).map(|mut url| { - url.set_query(Some(&format!("thread={thread_starter_msg_id}"))); + url.set_query(Some(&format!("thread={}", thread_starter_msg_id.0))); url }) } diff --git a/src/types/message_id.rs b/src/types/message_id.rs index fe3eb9ab..88a90902 100644 --- a/src/types/message_id.rs +++ b/src/types/message_id.rs @@ -1,8 +1,24 @@ use serde::{Deserialize, Serialize}; -/// This object represents a unique message identifier. +/// A unique message identifier. #[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)] -pub struct MessageId { - /// Unique message identifier - pub message_id: i32, +pub struct MessageId(#[serde(rename = "message_id")] pub i32); + +#[cfg(test)] +mod tests { + use crate::types::MessageId; + + #[test] + fn smoke_deser() { + let json = r#"{"message_id":123}"#; + let mid: MessageId = serde_json::from_str(json).unwrap(); + assert_eq!(mid, MessageId(123)); + } + + #[test] + fn smoke_ser() { + let mid: MessageId = MessageId(123); + let json = serde_json::to_string(&mid).unwrap(); + assert_eq!(json, r#"{"message_id":123}"#); + } } diff --git a/src/types/target_message.rs b/src/types/target_message.rs index 66f2409e..e851be06 100644 --- a/src/types/target_message.rs +++ b/src/types/target_message.rs @@ -1,4 +1,4 @@ -use crate::types::Recipient; +use crate::types::{MessageId, Recipient}; use serde::{Deserialize, Serialize}; @@ -6,8 +6,14 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] #[serde(untagged)] pub enum TargetMessage { - Common { chat_id: Recipient, message_id: i32 }, - Inline { inline_message_id: String }, + Common { + chat_id: Recipient, + #[serde(flatten)] + message_id: MessageId, + }, + Inline { + inline_message_id: String, + }, } impl From for TargetMessage { From f5a3b55435f314f48019e1f7b4973739d4a114b5 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 26 Sep 2022 22:59:58 +0400 Subject: [PATCH 2/5] Use typed `MessageId` in methods --- schema.ron | 56 +++++++++++----------- src/adaptors/erased.rs | 48 +++++++++---------- src/bot/api.rs | 36 +++++++++----- src/local_macros.rs | 48 +++++++++---------- src/payloads/codegen.rs | 9 +++- src/payloads/copy_message.rs | 6 ++- src/payloads/delete_message.rs | 5 +- src/payloads/edit_message_caption.rs | 5 +- src/payloads/edit_message_live_location.rs | 5 +- src/payloads/edit_message_media.rs | 5 +- src/payloads/edit_message_reply_markup.rs | 5 +- src/payloads/edit_message_text.rs | 5 +- src/payloads/forward_message.rs | 5 +- src/payloads/pin_chat_message.rs | 5 +- src/payloads/send_animation.rs | 7 ++- src/payloads/send_audio.rs | 7 ++- src/payloads/send_contact.rs | 5 +- src/payloads/send_dice.rs | 5 +- src/payloads/send_document.rs | 7 ++- src/payloads/send_location.rs | 5 +- src/payloads/send_media_group.rs | 5 +- src/payloads/send_message.rs | 5 +- src/payloads/send_photo.rs | 7 ++- src/payloads/send_poll.rs | 7 ++- src/payloads/send_venue.rs | 5 +- src/payloads/send_video.rs | 7 ++- src/payloads/send_video_note.rs | 5 +- src/payloads/send_voice.rs | 7 ++- src/payloads/set_game_score.rs | 5 +- src/payloads/stop_message_live_location.rs | 5 +- src/payloads/stop_poll.rs | 5 +- src/payloads/unpin_chat_message.rs | 5 +- src/requests/requester.rs | 33 ++++++++----- src/types.rs | 11 +++++ src/types/message.rs | 10 ++-- src/types/message_id.rs | 2 +- src/types/update.rs | 4 +- 37 files changed, 243 insertions(+), 164 deletions(-) diff --git a/schema.ron b/schema.ron index b5d6d0c2..dfe1e459 100644 --- a/schema.ron +++ b/schema.ron @@ -268,7 +268,7 @@ Schema( ), Param( name: "reply_to_message_id", - ty: Option(i32), + ty: Option(RawTy("MessageId")), descr: Doc(md: "If the message is a reply, ID of the original message") ), Param( @@ -324,7 +324,7 @@ Schema( ), Param( name: "message_id", - ty: i32, + ty: RawTy("MessageId"), descr: Doc(md: "Message identifier in the chat specified in _from\\_chat\\_id_") ), ], @@ -351,7 +351,7 @@ Schema( ), Param( name: "message_id", - ty: i32, + ty: RawTy("MessageId"), descr: Doc(md: "Message identifier in the chat specified in _from\\_chat\\_id_") ), Param( @@ -387,7 +387,7 @@ Schema( ), Param( name: "reply_to_message_id", - ty: Option(i32), + ty: Option(RawTy("MessageId")), descr: Doc(md: "If the message is a reply, ID of the original message") ), Param( @@ -464,7 +464,7 @@ Schema( ), Param( name: "reply_to_message_id", - ty: Option(i32), + ty: Option(RawTy("MessageId")), descr: Doc(md: "If the message is a reply, ID of the original message") ), Param( @@ -567,7 +567,7 @@ Schema( ), Param( name: "reply_to_message_id", - ty: Option(i32), + ty: Option(RawTy("MessageId")), descr: Doc(md: "If the message is a reply, ID of the original message") ), Param( @@ -657,7 +657,7 @@ Schema( ), Param( name: "reply_to_message_id", - ty: Option(i32), + ty: Option(RawTy("MessageId")), descr: Doc(md: "If the message is a reply, ID of the original message") ), Param( @@ -765,7 +765,7 @@ Schema( ), Param( name: "reply_to_message_id", - ty: Option(i32), + ty: Option(RawTy("MessageId")), descr: Doc(md: "If the message is a reply, ID of the original message") ), Param( @@ -866,7 +866,7 @@ Schema( ), Param( name: "reply_to_message_id", - ty: Option(i32), + ty: Option(RawTy("MessageId")), descr: Doc(md: "If the message is a reply, ID of the original message") ), Param( @@ -947,7 +947,7 @@ Schema( ), Param( name: "reply_to_message_id", - ty: Option(i32), + ty: Option(RawTy("MessageId")), descr: Doc(md: "If the message is a reply, ID of the original message") ), Param( @@ -1027,7 +1027,7 @@ Schema( ), Param( name: "reply_to_message_id", - ty: Option(i32), + ty: Option(RawTy("MessageId")), descr: Doc(md: "If the message is a reply, ID of the original message") ), Param( @@ -1084,7 +1084,7 @@ Schema( ), Param( name: "reply_to_message_id", - ty: Option(i32), + ty: Option(RawTy("MessageId")), descr: Doc(md: "If the message is a reply, ID of the original message") ), Param( @@ -1157,7 +1157,7 @@ Schema( ), Param( name: "reply_to_message_id", - ty: Option(i32), + ty: Option(RawTy("MessageId")), descr: Doc(md: "If the message is a reply, ID of the original message") ), Param( @@ -1195,7 +1195,7 @@ Schema( ), Param( name: "message_id", - ty: i32, + ty: RawTy("MessageId"), descr: Doc(md: "Identifier of the message to edit") ), Param( @@ -1311,7 +1311,7 @@ Schema( ), Param( name: "message_id", - ty: i32, + ty: RawTy("MessageId"), descr: Doc(md: "Identifier of the message to edit") ), Param( @@ -1450,7 +1450,7 @@ Schema( ), Param( name: "reply_to_message_id", - ty: Option(i32), + ty: Option(RawTy("MessageId")), descr: Doc(md: "If the message is a reply, ID of the original message") ), Param( @@ -1524,7 +1524,7 @@ Schema( ), Param( name: "reply_to_message_id", - ty: Option(i32), + ty: Option(RawTy("MessageId")), descr: Doc(md: "If the message is a reply, ID of the original message") ), Param( @@ -1638,7 +1638,7 @@ Schema( ), Param( name: "reply_to_message_id", - ty: Option(i32), + ty: Option(RawTy("MessageId")), descr: Doc(md: "If the message is a reply, ID of the original message") ), Param( @@ -1694,7 +1694,7 @@ Schema( ), Param( name: "reply_to_message_id", - ty: Option(i32), + ty: Option(RawTy("MessageId")), descr: Doc(md: "If the message is a reply, ID of the original message") ), Param( @@ -2311,7 +2311,7 @@ Schema( ), Param( name: "message_id", - ty: i32, + ty: RawTy("MessageId"), descr: Doc(md: "Identifier of a message to pin"), ), Param( @@ -2335,7 +2335,7 @@ Schema( ), Param( name: "message_id", - ty: Option(i32), + ty: Option(RawTy("MessageId")), descr: Doc(md: "Identifier of a message to unpin. If not specified, the most recent pinned message (by sending date) will be unpinned.") ), ], @@ -2760,7 +2760,7 @@ Schema( ), Param( name: "message_id", - ty: i32, + ty: RawTy("MessageId"), descr: Doc(md: "Identifier of the message to edit") ), Param( @@ -2860,7 +2860,7 @@ Schema( ), Param( name: "message_id", - ty: i32, + ty: RawTy("MessageId"), descr: Doc(md: "Identifier of the message to edit") ), Param( @@ -2948,7 +2948,7 @@ Schema( ), Param( name: "message_id", - ty: i32, + ty: RawTy("MessageId"), descr: Doc(md: "Identifier of the message to edit") ), Param( @@ -3009,7 +3009,7 @@ Schema( ), Param( name: "message_id", - ty: i32, + ty: RawTy("MessageId"), descr: Doc(md: "Identifier of the message to edit") ), Param( @@ -3059,7 +3059,7 @@ Schema( ), Param( name: "message_id", - ty: i32, + ty: RawTy("MessageId"), descr: Doc(md: "Identifier of the message to edit") ), Param( @@ -3086,7 +3086,7 @@ Schema( ), Param( name: "message_id", - ty: i32, + ty: RawTy("MessageId"), descr: Doc(md: "Identifier of the message to delete") ), ], @@ -3786,7 +3786,7 @@ Schema( ), Param( name: "message_id", - ty: i64, + ty: RawTy("MessageId"), descr: Doc(md: "Identifier of the message to edit") ), ], diff --git a/src/adaptors/erased.rs b/src/adaptors/erased.rs index aee6c21c..1cac5f5c 100644 --- a/src/adaptors/erased.rs +++ b/src/adaptors/erased.rs @@ -312,14 +312,14 @@ trait ErasableRequester<'a> { &self, chat_id: Recipient, from_chat_id: Recipient, - message_id: i32, + message_id: MessageId, ) -> ErasedRequest<'a, ForwardMessage, Self::Err>; fn copy_message( &self, chat_id: Recipient, from_chat_id: Recipient, - message_id: i32, + message_id: MessageId, ) -> ErasedRequest<'a, CopyMessage, Self::Err>; fn send_photo( @@ -380,7 +380,7 @@ trait ErasableRequester<'a> { fn edit_message_live_location( &self, chat_id: Recipient, - message_id: i32, + message_id: MessageId, latitude: f64, longitude: f64, ) -> ErasedRequest<'a, EditMessageLiveLocation, Self::Err>; @@ -395,7 +395,7 @@ trait ErasableRequester<'a> { fn stop_message_live_location( &self, chat_id: Recipient, - message_id: i32, + message_id: MessageId, latitude: f64, longitude: f64, ) -> ErasedRequest<'a, StopMessageLiveLocation, Self::Err>; @@ -562,7 +562,7 @@ trait ErasableRequester<'a> { fn pin_chat_message( &self, chat_id: Recipient, - message_id: i32, + message_id: MessageId, ) -> ErasedRequest<'a, PinChatMessage, Self::Err>; fn unpin_chat_message( @@ -652,7 +652,7 @@ trait ErasableRequester<'a> { fn edit_message_text( &self, chat_id: Recipient, - message_id: i32, + message_id: MessageId, text: String, ) -> ErasedRequest<'a, EditMessageText, Self::Err>; @@ -665,7 +665,7 @@ trait ErasableRequester<'a> { fn edit_message_caption( &self, chat_id: Recipient, - message_id: i32, + message_id: MessageId, ) -> ErasedRequest<'a, EditMessageCaption, Self::Err>; fn edit_message_caption_inline( @@ -676,7 +676,7 @@ trait ErasableRequester<'a> { fn edit_message_media( &self, chat_id: Recipient, - message_id: i32, + message_id: MessageId, media: InputMedia, ) -> ErasedRequest<'a, EditMessageMedia, Self::Err>; @@ -689,7 +689,7 @@ trait ErasableRequester<'a> { fn edit_message_reply_markup( &self, chat_id: Recipient, - message_id: i32, + message_id: MessageId, ) -> ErasedRequest<'a, EditMessageReplyMarkup, Self::Err>; fn edit_message_reply_markup_inline( @@ -700,13 +700,13 @@ trait ErasableRequester<'a> { fn stop_poll( &self, chat_id: Recipient, - message_id: i32, + message_id: MessageId, ) -> ErasedRequest<'a, StopPoll, Self::Err>; fn delete_message( &self, chat_id: Recipient, - message_id: i32, + message_id: MessageId, ) -> ErasedRequest<'a, DeleteMessage, Self::Err>; fn send_sticker( @@ -815,7 +815,7 @@ trait ErasableRequester<'a> { user_id: UserId, score: u64, chat_id: u32, - message_id: i64, + message_id: MessageId, ) -> ErasedRequest<'a, SetGameScore, Self::Err>; fn set_game_score_inline( @@ -878,7 +878,7 @@ where &self, chat_id: Recipient, from_chat_id: Recipient, - message_id: i32, + message_id: MessageId, ) -> ErasedRequest<'a, ForwardMessage, Self::Err> { Requester::forward_message(self, chat_id, from_chat_id, message_id).erase() } @@ -887,7 +887,7 @@ where &self, chat_id: Recipient, from_chat_id: Recipient, - message_id: i32, + message_id: MessageId, ) -> ErasedRequest<'a, CopyMessage, Self::Err> { Requester::copy_message(self, chat_id, from_chat_id, message_id).erase() } @@ -968,7 +968,7 @@ where fn edit_message_live_location( &self, chat_id: Recipient, - message_id: i32, + message_id: MessageId, latitude: f64, longitude: f64, ) -> ErasedRequest<'a, EditMessageLiveLocation, Self::Err> { @@ -989,7 +989,7 @@ where fn stop_message_live_location( &self, chat_id: Recipient, - message_id: i32, + message_id: MessageId, latitude: f64, longitude: f64, ) -> ErasedRequest<'a, StopMessageLiveLocation, Self::Err> { @@ -1214,7 +1214,7 @@ where fn pin_chat_message( &self, chat_id: Recipient, - message_id: i32, + message_id: MessageId, ) -> ErasedRequest<'a, PinChatMessage, Self::Err> { Requester::pin_chat_message(self, chat_id, message_id).erase() } @@ -1346,7 +1346,7 @@ where fn edit_message_text( &self, chat_id: Recipient, - message_id: i32, + message_id: MessageId, text: String, ) -> ErasedRequest<'a, EditMessageText, Self::Err> { Requester::edit_message_text(self, chat_id, message_id, text).erase() @@ -1363,7 +1363,7 @@ where fn edit_message_caption( &self, chat_id: Recipient, - message_id: i32, + message_id: MessageId, ) -> ErasedRequest<'a, EditMessageCaption, Self::Err> { Requester::edit_message_caption(self, chat_id, message_id).erase() } @@ -1378,7 +1378,7 @@ where fn edit_message_media( &self, chat_id: Recipient, - message_id: i32, + message_id: MessageId, media: InputMedia, ) -> ErasedRequest<'a, EditMessageMedia, Self::Err> { Requester::edit_message_media(self, chat_id, message_id, media).erase() @@ -1395,7 +1395,7 @@ where fn edit_message_reply_markup( &self, chat_id: Recipient, - message_id: i32, + message_id: MessageId, ) -> ErasedRequest<'a, EditMessageReplyMarkup, Self::Err> { Requester::edit_message_reply_markup(self, chat_id, message_id).erase() } @@ -1410,7 +1410,7 @@ where fn stop_poll( &self, chat_id: Recipient, - message_id: i32, + message_id: MessageId, ) -> ErasedRequest<'a, StopPoll, Self::Err> { Requester::stop_poll(self, chat_id, message_id).erase() } @@ -1418,7 +1418,7 @@ where fn delete_message( &self, chat_id: Recipient, - message_id: i32, + message_id: MessageId, ) -> ErasedRequest<'a, DeleteMessage, Self::Err> { Requester::delete_message(self, chat_id, message_id).erase() } @@ -1576,7 +1576,7 @@ where user_id: UserId, score: u64, chat_id: u32, - message_id: i64, + message_id: MessageId, ) -> ErasedRequest<'a, SetGameScore, Self::Err> { Requester::set_game_score(self, user_id, score, chat_id, message_id).erase() } diff --git a/src/bot/api.rs b/src/bot/api.rs index d78cad73..f0fbfa78 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -6,7 +6,7 @@ use crate::{ requests::{JsonRequest, MultipartRequest}, types::{ BotCommand, ChatId, ChatPermissions, InlineQueryResult, InputFile, InputMedia, - InputSticker, LabeledPrice, Recipient, UserId, + InputSticker, LabeledPrice, MessageId, Recipient, UserId, }, Bot, }; @@ -60,7 +60,7 @@ impl Requester for Bot { &self, chat_id: C, from_chat_id: F, - message_id: i32, + message_id: MessageId, ) -> Self::ForwardMessage where C: Into, @@ -168,7 +168,7 @@ impl Requester for Bot { fn edit_message_live_location( &self, chat_id: C, - message_id: i32, + message_id: MessageId, latitude: f64, longitude: f64, ) -> Self::EditMessageLiveLocation @@ -203,7 +203,7 @@ impl Requester for Bot { fn stop_message_live_location( &self, chat_id: C, - message_id: i32, + message_id: MessageId, latitude: f64, longitude: f64, ) -> Self::StopMessageLiveLocation @@ -564,7 +564,7 @@ impl Requester for Bot { type PinChatMessage = JsonRequest; - fn pin_chat_message(&self, chat_id: C, message_id: i32) -> Self::PinChatMessage + fn pin_chat_message(&self, chat_id: C, message_id: MessageId) -> Self::PinChatMessage where C: Into, { @@ -756,7 +756,12 @@ impl Requester for Bot { type EditMessageText = JsonRequest; - fn edit_message_text(&self, chat_id: C, message_id: i32, text: T) -> Self::EditMessageText + fn edit_message_text( + &self, + chat_id: C, + message_id: MessageId, + text: T, + ) -> Self::EditMessageText where C: Into, T: Into, @@ -786,7 +791,7 @@ impl Requester for Bot { type EditMessageCaption = JsonRequest; - fn edit_message_caption(&self, chat_id: C, message_id: i32) -> Self::EditMessageCaption + fn edit_message_caption(&self, chat_id: C, message_id: MessageId) -> Self::EditMessageCaption where C: Into, { @@ -813,7 +818,7 @@ impl Requester for Bot { fn edit_message_media( &self, chat_id: C, - message_id: i32, + message_id: MessageId, media: InputMedia, ) -> Self::EditMessageMedia where @@ -846,7 +851,7 @@ impl Requester for Bot { fn edit_message_reply_markup( &self, chat_id: C, - message_id: i32, + message_id: MessageId, ) -> Self::EditMessageReplyMarkup where C: Into, @@ -874,7 +879,7 @@ impl Requester for Bot { type StopPoll = JsonRequest; - fn stop_poll(&self, chat_id: C, message_id: i32) -> Self::StopPoll + fn stop_poll(&self, chat_id: C, message_id: MessageId) -> Self::StopPoll where C: Into, { @@ -883,7 +888,7 @@ impl Requester for Bot { type DeleteMessage = JsonRequest; - fn delete_message(&self, chat_id: C, message_id: i32) -> Self::DeleteMessage + fn delete_message(&self, chat_id: C, message_id: MessageId) -> Self::DeleteMessage where C: Into, { @@ -1139,7 +1144,7 @@ impl Requester for Bot { user_id: UserId, score: u64, chat_id: u32, - message_id: i64, + message_id: MessageId, ) -> Self::SetGameScore { Self::SetGameScore::new( self.clone(), @@ -1190,7 +1195,12 @@ impl Requester for Bot { type CopyMessage = JsonRequest; - fn copy_message(&self, chat_id: C, from_chat_id: F, message_id: i32) -> Self::CopyMessage + fn copy_message( + &self, + chat_id: C, + from_chat_id: F, + message_id: MessageId, + ) -> Self::CopyMessage where C: Into, F: Into, diff --git a/src/local_macros.rs b/src/local_macros.rs index 56659c5e..8ab0370f 100644 --- a/src/local_macros.rs +++ b/src/local_macros.rs @@ -479,19 +479,19 @@ macro_rules! requester_forward { (@method forward_message $body:ident $ty:ident) => { type ForwardMessage = $ty![ForwardMessage]; - fn forward_message(&self, chat_id: C, from_chat_id: F, message_id: i32) -> Self::ForwardMessage where C: Into, + fn forward_message(&self, chat_id: C, from_chat_id: F, message_id: MessageId) -> Self::ForwardMessage where C: Into, F: Into { let this = self; - $body!(forward_message this (chat_id: C, from_chat_id: F, message_id: i32)) + $body!(forward_message this (chat_id: C, from_chat_id: F, message_id: MessageId)) } }; (@method copy_message $body:ident $ty:ident) => { type CopyMessage = $ty![CopyMessage]; - fn copy_message(&self, chat_id: C, from_chat_id: F, message_id: i32) -> Self::CopyMessage where C: Into, + fn copy_message(&self, chat_id: C, from_chat_id: F, message_id: MessageId) -> Self::CopyMessage where C: Into, F: Into { let this = self; - $body!(copy_message this (chat_id: C, from_chat_id: F, message_id: i32)) + $body!(copy_message this (chat_id: C, from_chat_id: F, message_id: MessageId)) } }; (@method send_photo $body:ident $ty:ident) => { @@ -570,9 +570,9 @@ macro_rules! requester_forward { (@method edit_message_live_location $body:ident $ty:ident) => { type EditMessageLiveLocation = $ty![EditMessageLiveLocation]; - fn edit_message_live_location(&self, chat_id: C, message_id: i32, latitude: f64, longitude: f64) -> Self::EditMessageLiveLocation where C: Into { + fn edit_message_live_location(&self, chat_id: C, message_id: MessageId, latitude: f64, longitude: f64) -> Self::EditMessageLiveLocation where C: Into { let this = self; - $body!(edit_message_live_location this (chat_id: C, message_id: i32, latitude: f64, longitude: f64)) + $body!(edit_message_live_location this (chat_id: C, message_id: MessageId, latitude: f64, longitude: f64)) } }; (@method edit_message_live_location_inline $body:ident $ty:ident) => { @@ -586,9 +586,9 @@ macro_rules! requester_forward { (@method stop_message_live_location $body:ident $ty:ident) => { type StopMessageLiveLocation = $ty![StopMessageLiveLocation]; - fn stop_message_live_location(&self, chat_id: C, message_id: i32, latitude: f64, longitude: f64) -> Self::StopMessageLiveLocation where C: Into { + fn stop_message_live_location(&self, chat_id: C, message_id: MessageId, latitude: f64, longitude: f64) -> Self::StopMessageLiveLocation where C: Into { let this = self; - $body!(stop_message_live_location this (chat_id: C, message_id: i32, latitude: f64, longitude: f64)) + $body!(stop_message_live_location this (chat_id: C, message_id: MessageId, latitude: f64, longitude: f64)) } }; (@method stop_message_live_location_inline $body:ident $ty:ident) => { @@ -822,9 +822,9 @@ macro_rules! requester_forward { (@method pin_chat_message $body:ident $ty:ident) => { type PinChatMessage = $ty![PinChatMessage]; - fn pin_chat_message(&self, chat_id: C, message_id: i32) -> Self::PinChatMessage where C: Into { + fn pin_chat_message(&self, chat_id: C, message_id: MessageId) -> Self::PinChatMessage where C: Into { let this = self; - $body!(pin_chat_message this (chat_id: C, message_id: i32)) + $body!(pin_chat_message this (chat_id: C, message_id: MessageId)) } }; (@method unpin_chat_message $body:ident $ty:ident) => { @@ -992,10 +992,10 @@ macro_rules! requester_forward { (@method edit_message_text $body:ident $ty:ident) => { type EditMessageText = $ty![EditMessageText]; - fn edit_message_text(&self, chat_id: C, message_id: i32, text: T) -> Self::EditMessageText where C: Into, + fn edit_message_text(&self, chat_id: C, message_id: MessageId, text: T) -> Self::EditMessageText where C: Into, T: Into { let this = self; - $body!(edit_message_text this (chat_id: C, message_id: i32, text: T)) + $body!(edit_message_text this (chat_id: C, message_id: MessageId, text: T)) } }; (@method edit_message_text_inline $body:ident $ty:ident) => { @@ -1010,9 +1010,9 @@ macro_rules! requester_forward { (@method edit_message_caption $body:ident $ty:ident) => { type EditMessageCaption = $ty![EditMessageCaption]; - fn edit_message_caption(&self, chat_id: C, message_id: i32) -> Self::EditMessageCaption where C: Into { + fn edit_message_caption(&self, chat_id: C, message_id: MessageId) -> Self::EditMessageCaption where C: Into { let this = self; - $body!(edit_message_caption this (chat_id: C, message_id: i32)) + $body!(edit_message_caption this (chat_id: C, message_id: MessageId)) } }; (@method edit_message_caption_inline $body:ident $ty:ident) => { @@ -1026,9 +1026,9 @@ macro_rules! requester_forward { (@method edit_message_media $body:ident $ty:ident) => { type EditMessageMedia = $ty![EditMessageMedia]; - fn edit_message_media(&self, chat_id: C, message_id: i32, media: InputMedia) -> Self::EditMessageMedia where C: Into { + fn edit_message_media(&self, chat_id: C, message_id: MessageId, media: InputMedia) -> Self::EditMessageMedia where C: Into { let this = self; - $body!(edit_message_media this (chat_id: C, message_id: i32, media: InputMedia)) + $body!(edit_message_media this (chat_id: C, message_id: MessageId, media: InputMedia)) } }; (@method edit_message_media_inline $body:ident $ty:ident) => { @@ -1042,9 +1042,9 @@ macro_rules! requester_forward { (@method edit_message_reply_markup $body:ident $ty:ident) => { type EditMessageReplyMarkup = $ty![EditMessageReplyMarkup]; - fn edit_message_reply_markup(&self, chat_id: C, message_id: i32) -> Self::EditMessageReplyMarkup where C: Into { + fn edit_message_reply_markup(&self, chat_id: C, message_id: MessageId) -> Self::EditMessageReplyMarkup where C: Into { let this = self; - $body!(edit_message_reply_markup this (chat_id: C, message_id: i32)) + $body!(edit_message_reply_markup this (chat_id: C, message_id: MessageId)) } }; (@method edit_message_reply_markup_inline $body:ident $ty:ident) => { @@ -1058,17 +1058,17 @@ macro_rules! requester_forward { (@method stop_poll $body:ident $ty:ident) => { type StopPoll = $ty![StopPoll]; - fn stop_poll(&self, chat_id: C, message_id: i32) -> Self::StopPoll where C: Into { + fn stop_poll(&self, chat_id: C, message_id: MessageId) -> Self::StopPoll where C: Into { let this = self; - $body!(stop_poll this (chat_id: C, message_id: i32)) + $body!(stop_poll this (chat_id: C, message_id: MessageId)) } }; (@method delete_message $body:ident $ty:ident) => { type DeleteMessage = $ty![DeleteMessage]; - fn delete_message(&self, chat_id: C, message_id: i32) -> Self::DeleteMessage where C: Into { + fn delete_message(&self, chat_id: C, message_id: MessageId) -> Self::DeleteMessage where C: Into { let this = self; - $body!(delete_message this (chat_id: C, message_id: i32)) + $body!(delete_message this (chat_id: C, message_id: MessageId)) } }; (@method send_sticker $body:ident $ty:ident) => { @@ -1208,9 +1208,9 @@ macro_rules! requester_forward { (@method set_game_score $body:ident $ty:ident) => { type SetGameScore = $ty![SetGameScore]; - fn set_game_score(&self, user_id: UserId, score: u64, chat_id: u32, message_id: i64) -> Self::SetGameScore { + fn set_game_score(&self, user_id: UserId, score: u64, chat_id: u32, message_id: MessageId) -> Self::SetGameScore { let this = self; - $body!(set_game_score this (user_id: UserId, score: u64, chat_id: u32, message_id: i64)) + $body!(set_game_score this (user_id: UserId, score: u64, chat_id: u32, message_id: MessageId)) } }; (@method set_game_score_inline $body:ident $ty:ident) => { diff --git a/src/payloads/codegen.rs b/src/payloads/codegen.rs index 6cc60bad..0032f9a5 100644 --- a/src/payloads/codegen.rs +++ b/src/payloads/codegen.rs @@ -222,8 +222,15 @@ fn params(params: impl Iterator>) -> String { let field = ¶m.name; let ty = ¶m.ty; let flatten = match ty { + Type::RawTy(s) if s == "MessageId" && field == "reply_to_message_id" => { + "\n #[serde(serialize_with = \ + \"crate::types::serialize_reply_to_message_id\")]" + } Type::RawTy(s) - if s == "InputSticker" || s == "TargetMessage" || s == "StickerType" => + if s == "MessageId" + || s == "InputSticker" + || s == "TargetMessage" + || s == "StickerType" => { "\n #[serde(flatten)]" } diff --git a/src/payloads/copy_message.rs b/src/payloads/copy_message.rs index 39f1688c..b614b79e 100644 --- a/src/payloads/copy_message.rs +++ b/src/payloads/copy_message.rs @@ -16,7 +16,8 @@ impl_payload! { /// Unique identifier for the chat where the original message was sent (or channel username in the format `@channelusername`) pub from_chat_id: Recipient [into], /// Message identifier in the chat specified in _from\_chat\_id_ - pub message_id: i32, + #[serde(flatten)] + pub message_id: MessageId, } optional { /// New caption for media, 0-1024 characters after entities parsing. If not specified, the original caption is kept @@ -34,7 +35,8 @@ impl_payload! { /// Protects the contents of sent messages from forwarding and saving pub protect_content: bool, /// If the message is a reply, ID of the original message - pub reply_to_message_id: i32, + #[serde(serialize_with = "crate::types::serialize_reply_to_message_id")] + pub reply_to_message_id: MessageId, /// Pass _True_, if the message should be sent even if the specified replied-to message is not found pub allow_sending_without_reply: bool, /// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user. diff --git a/src/payloads/delete_message.rs b/src/payloads/delete_message.rs index 4214ad7b..8503c4dd 100644 --- a/src/payloads/delete_message.rs +++ b/src/payloads/delete_message.rs @@ -2,7 +2,7 @@ use serde::Serialize; -use crate::types::{Recipient, True}; +use crate::types::{MessageId, Recipient, True}; impl_payload! { /// Use this method to delete a message, including service messages, with the following limitations: @@ -21,7 +21,8 @@ impl_payload! { /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`). pub chat_id: Recipient [into], /// Identifier of the message to delete - pub message_id: i32, + #[serde(flatten)] + pub message_id: MessageId, } } } diff --git a/src/payloads/edit_message_caption.rs b/src/payloads/edit_message_caption.rs index f31cce35..4f993098 100644 --- a/src/payloads/edit_message_caption.rs +++ b/src/payloads/edit_message_caption.rs @@ -2,7 +2,7 @@ use serde::Serialize; -use crate::types::{InlineKeyboardMarkup, Message, MessageEntity, ParseMode, Recipient}; +use crate::types::{InlineKeyboardMarkup, Message, MessageEntity, MessageId, ParseMode, Recipient}; impl_payload! { /// Use this method to edit captions of messages. On success, the edited Message is returned. @@ -14,7 +14,8 @@ impl_payload! { /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`). pub chat_id: Recipient [into], /// Identifier of the message to edit - pub message_id: i32, + #[serde(flatten)] + pub message_id: MessageId, } optional { /// New caption of the message, 0-1024 characters after entities parsing diff --git a/src/payloads/edit_message_live_location.rs b/src/payloads/edit_message_live_location.rs index c9400abd..b8df0e5a 100644 --- a/src/payloads/edit_message_live_location.rs +++ b/src/payloads/edit_message_live_location.rs @@ -2,7 +2,7 @@ use serde::Serialize; -use crate::types::{Message, Recipient, ReplyMarkup}; +use crate::types::{Message, MessageId, Recipient, ReplyMarkup}; impl_payload! { /// Use this method to edit live location messages. A location can be edited until its live_period expires or editing is explicitly disabled by a call to [`StopMessageLiveLocation`]. On success, the edited Message is returned. @@ -16,7 +16,8 @@ impl_payload! { /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) pub chat_id: Recipient [into], /// Identifier of the message to edit - pub message_id: i32, + #[serde(flatten)] + pub message_id: MessageId, /// Latitude of new location pub latitude: f64, /// Longitude of new location diff --git a/src/payloads/edit_message_media.rs b/src/payloads/edit_message_media.rs index 9cbba6aa..917a13b7 100644 --- a/src/payloads/edit_message_media.rs +++ b/src/payloads/edit_message_media.rs @@ -2,7 +2,7 @@ use serde::Serialize; -use crate::types::{InlineKeyboardMarkup, InputMedia, Message, Recipient}; +use crate::types::{InlineKeyboardMarkup, InputMedia, Message, MessageId, Recipient}; impl_payload! { /// Use this method to edit animation, audio, document, photo, or video messages. If a message is a part of a message album, then it can be edited only to a photo or a video. Otherwise, message type can be changed arbitrarily. When inline message is edited, new file can't be uploaded. Use previously uploaded file via its file_id or specify a URL. On success, the edited Message is returned. @@ -14,7 +14,8 @@ impl_payload! { /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`). pub chat_id: Recipient [into], /// Identifier of the message to edit - pub message_id: i32, + #[serde(flatten)] + pub message_id: MessageId, /// A JSON-serialized object for a new media content of the message pub media: InputMedia, } diff --git a/src/payloads/edit_message_reply_markup.rs b/src/payloads/edit_message_reply_markup.rs index a6402bd3..dd64252d 100644 --- a/src/payloads/edit_message_reply_markup.rs +++ b/src/payloads/edit_message_reply_markup.rs @@ -2,7 +2,7 @@ use serde::Serialize; -use crate::types::{InlineKeyboardMarkup, Message, Recipient}; +use crate::types::{InlineKeyboardMarkup, Message, MessageId, Recipient}; impl_payload! { /// Use this method to edit only the reply markup of messages. On success, the edited Message is returned. @@ -14,7 +14,8 @@ impl_payload! { /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`). pub chat_id: Recipient [into], /// Identifier of the message to edit - pub message_id: i32, + #[serde(flatten)] + pub message_id: MessageId, } optional { /// A JSON-serialized object for an [inline keyboard]. diff --git a/src/payloads/edit_message_text.rs b/src/payloads/edit_message_text.rs index 18adde6f..ba4329c5 100644 --- a/src/payloads/edit_message_text.rs +++ b/src/payloads/edit_message_text.rs @@ -2,7 +2,7 @@ use serde::Serialize; -use crate::types::{InlineKeyboardMarkup, Message, MessageEntity, ParseMode, Recipient}; +use crate::types::{InlineKeyboardMarkup, Message, MessageEntity, MessageId, ParseMode, Recipient}; impl_payload! { /// Use this method to edit text and [games] messages. On success, the edited Message is returned. @@ -16,7 +16,8 @@ impl_payload! { /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`). pub chat_id: Recipient [into], /// Identifier of the message to edit - pub message_id: i32, + #[serde(flatten)] + pub message_id: MessageId, /// New text of the message, 1-4096 characters after entities parsing pub text: String [into], } diff --git a/src/payloads/forward_message.rs b/src/payloads/forward_message.rs index 762ff542..1e4c079c 100644 --- a/src/payloads/forward_message.rs +++ b/src/payloads/forward_message.rs @@ -2,7 +2,7 @@ use serde::Serialize; -use crate::types::{Message, Recipient}; +use crate::types::{Message, MessageId, Recipient}; impl_payload! { /// Use this method to forward messages of any kind. On success, the sent [`Message`] is returned. @@ -16,7 +16,8 @@ impl_payload! { /// Unique identifier for the chat where the original message was sent (or channel username in the format `@channelusername`) pub from_chat_id: Recipient [into], /// Message identifier in the chat specified in _from\_chat\_id_ - pub message_id: i32, + #[serde(flatten)] + pub message_id: MessageId, } optional { /// Sends the message [silently]. Users will receive a notification with no sound. diff --git a/src/payloads/pin_chat_message.rs b/src/payloads/pin_chat_message.rs index 960ea24c..fd217bac 100644 --- a/src/payloads/pin_chat_message.rs +++ b/src/payloads/pin_chat_message.rs @@ -2,7 +2,7 @@ use serde::Serialize; -use crate::types::{Recipient, True}; +use crate::types::{MessageId, Recipient, True}; impl_payload! { /// Use this method to pin a message in a group, a supergroup, or a channel. The bot must be an administrator in the chat for this to work and must have the 'can_pin_messages' admin right in the supergroup or 'can_edit_messages' admin right in the channel. Returns _True_ on success. @@ -12,7 +12,8 @@ impl_payload! { /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) pub chat_id: Recipient [into], /// Identifier of a message to pin - pub message_id: i32, + #[serde(flatten)] + pub message_id: MessageId, } optional { /// Pass True, if it is not necessary to send a notification to all chat members about the new pinned message. Notifications are always disabled in channels. diff --git a/src/payloads/send_animation.rs b/src/payloads/send_animation.rs index 4082b046..118e1044 100644 --- a/src/payloads/send_animation.rs +++ b/src/payloads/send_animation.rs @@ -2,7 +2,9 @@ use serde::Serialize; -use crate::types::{InputFile, Message, MessageEntity, ParseMode, Recipient, ReplyMarkup}; +use crate::types::{ + InputFile, Message, MessageEntity, MessageId, ParseMode, Recipient, ReplyMarkup, +}; impl_payload! { @[multipart = animation, thumb] @@ -45,7 +47,8 @@ impl_payload! { /// Protects the contents of sent messages from forwarding and saving pub protect_content: bool, /// If the message is a reply, ID of the original message - pub reply_to_message_id: i32, + #[serde(serialize_with = "crate::types::serialize_reply_to_message_id")] + pub reply_to_message_id: MessageId, /// Pass _True_, if the message should be sent even if the specified replied-to message is not found pub allow_sending_without_reply: bool, /// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user. diff --git a/src/payloads/send_audio.rs b/src/payloads/send_audio.rs index 7f5e4adb..05b5c6ca 100644 --- a/src/payloads/send_audio.rs +++ b/src/payloads/send_audio.rs @@ -2,7 +2,9 @@ use serde::Serialize; -use crate::types::{InputFile, Message, MessageEntity, ParseMode, Recipient, ReplyMarkup}; +use crate::types::{ + InputFile, Message, MessageEntity, MessageId, ParseMode, Recipient, ReplyMarkup, +}; impl_payload! { @[multipart = audio, thumb] @@ -48,7 +50,8 @@ impl_payload! { /// Protects the contents of sent messages from forwarding and saving pub protect_content: bool, /// If the message is a reply, ID of the original message - pub reply_to_message_id: i32, + #[serde(serialize_with = "crate::types::serialize_reply_to_message_id")] + pub reply_to_message_id: MessageId, /// Pass _True_, if the message should be sent even if the specified replied-to message is not found pub allow_sending_without_reply: bool, /// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user. diff --git a/src/payloads/send_contact.rs b/src/payloads/send_contact.rs index 06632a21..d96b1faa 100644 --- a/src/payloads/send_contact.rs +++ b/src/payloads/send_contact.rs @@ -2,7 +2,7 @@ use serde::Serialize; -use crate::types::{Message, Recipient, ReplyMarkup}; +use crate::types::{Message, MessageId, Recipient, ReplyMarkup}; impl_payload! { /// Use this method to send phone contacts. On success, the sent [`Message`] is returned. @@ -32,7 +32,8 @@ impl_payload! { /// Protects the contents of sent messages from forwarding and saving pub protect_content: bool, /// If the message is a reply, ID of the original message - pub reply_to_message_id: i32, + #[serde(serialize_with = "crate::types::serialize_reply_to_message_id")] + pub reply_to_message_id: MessageId, /// Pass _True_, if the message should be sent even if the specified replied-to message is not found pub allow_sending_without_reply: bool, /// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user. diff --git a/src/payloads/send_dice.rs b/src/payloads/send_dice.rs index a7b74fe3..5a673cb9 100644 --- a/src/payloads/send_dice.rs +++ b/src/payloads/send_dice.rs @@ -2,7 +2,7 @@ use serde::Serialize; -use crate::types::{DiceEmoji, Message, Recipient, ReplyMarkup}; +use crate::types::{DiceEmoji, Message, MessageId, Recipient, ReplyMarkup}; impl_payload! { /// Use this method to send an animated emoji that will display a random value. On success, the sent [`Message`] is returned. @@ -24,7 +24,8 @@ impl_payload! { /// Protects the contents of sent messages from forwarding and saving pub protect_content: bool, /// If the message is a reply, ID of the original message - pub reply_to_message_id: i32, + #[serde(serialize_with = "crate::types::serialize_reply_to_message_id")] + pub reply_to_message_id: MessageId, /// Pass _True_, if the message should be sent even if the specified replied-to message is not found pub allow_sending_without_reply: bool, /// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user. diff --git a/src/payloads/send_document.rs b/src/payloads/send_document.rs index 1ee434f2..aaa684de 100644 --- a/src/payloads/send_document.rs +++ b/src/payloads/send_document.rs @@ -2,7 +2,9 @@ use serde::Serialize; -use crate::types::{InputFile, Message, MessageEntity, ParseMode, Recipient, ReplyMarkup}; +use crate::types::{ + InputFile, Message, MessageEntity, MessageId, ParseMode, Recipient, ReplyMarkup, +}; impl_payload! { @[multipart = document, thumb] @@ -41,7 +43,8 @@ impl_payload! { /// Protects the contents of sent messages from forwarding and saving pub protect_content: bool, /// If the message is a reply, ID of the original message - pub reply_to_message_id: i32, + #[serde(serialize_with = "crate::types::serialize_reply_to_message_id")] + pub reply_to_message_id: MessageId, /// Pass _True_, if the message should be sent even if the specified replied-to message is not found pub allow_sending_without_reply: bool, /// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user. diff --git a/src/payloads/send_location.rs b/src/payloads/send_location.rs index 556105b9..69a84cee 100644 --- a/src/payloads/send_location.rs +++ b/src/payloads/send_location.rs @@ -2,7 +2,7 @@ use serde::Serialize; -use crate::types::{Message, Recipient, ReplyMarkup}; +use crate::types::{Message, MessageId, Recipient, ReplyMarkup}; impl_payload! { /// Use this method to send point on the map. On success, the sent [`Message`] is returned. @@ -36,7 +36,8 @@ impl_payload! { /// Protects the contents of sent messages from forwarding and saving pub protect_content: bool, /// If the message is a reply, ID of the original message - pub reply_to_message_id: i32, + #[serde(serialize_with = "crate::types::serialize_reply_to_message_id")] + pub reply_to_message_id: MessageId, /// Pass _True_, if the message should be sent even if the specified replied-to message is not found pub allow_sending_without_reply: bool, /// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user. diff --git a/src/payloads/send_media_group.rs b/src/payloads/send_media_group.rs index db762c50..9d2b14fa 100644 --- a/src/payloads/send_media_group.rs +++ b/src/payloads/send_media_group.rs @@ -2,7 +2,7 @@ use serde::Serialize; -use crate::types::{InputMedia, Message, Recipient}; +use crate::types::{InputMedia, Message, MessageId, Recipient}; impl_payload! { /// Use this method to send a group of photos, videos, documents or audios as an album. Documents and audio files can be only grouped in an album with messages of the same type. On success, an array of [`Message`]s that were sent is returned. @@ -24,7 +24,8 @@ impl_payload! { /// Protects the contents of sent messages from forwarding and saving pub protect_content: bool, /// If the message is a reply, ID of the original message - pub reply_to_message_id: i32, + #[serde(serialize_with = "crate::types::serialize_reply_to_message_id")] + pub reply_to_message_id: MessageId, /// Pass _True_, if the message should be sent even if the specified replied-to message is not found pub allow_sending_without_reply: bool, } diff --git a/src/payloads/send_message.rs b/src/payloads/send_message.rs index fa0c2bbf..20899142 100644 --- a/src/payloads/send_message.rs +++ b/src/payloads/send_message.rs @@ -2,7 +2,7 @@ use serde::Serialize; -use crate::types::{Message, MessageEntity, ParseMode, Recipient, ReplyMarkup}; +use crate::types::{Message, MessageEntity, MessageId, ParseMode, Recipient, ReplyMarkup}; impl_payload! { /// Use this method to send text messages. On success, the sent [`Message`] is returned. @@ -32,7 +32,8 @@ impl_payload! { /// Protects the contents of sent messages from forwarding and saving pub protect_content: bool, /// If the message is a reply, ID of the original message - pub reply_to_message_id: i32, + #[serde(serialize_with = "crate::types::serialize_reply_to_message_id")] + pub reply_to_message_id: MessageId, /// Pass _True_, if the message should be sent even if the specified replied-to message is not found pub allow_sending_without_reply: bool, /// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user. diff --git a/src/payloads/send_photo.rs b/src/payloads/send_photo.rs index 782d7d27..50af80dd 100644 --- a/src/payloads/send_photo.rs +++ b/src/payloads/send_photo.rs @@ -2,7 +2,9 @@ use serde::Serialize; -use crate::types::{InputFile, Message, MessageEntity, ParseMode, Recipient, ReplyMarkup}; +use crate::types::{ + InputFile, Message, MessageEntity, MessageId, ParseMode, Recipient, ReplyMarkup, +}; impl_payload! { @[multipart = photo] @@ -35,7 +37,8 @@ impl_payload! { /// Protects the contents of sent messages from forwarding and saving pub protect_content: bool, /// If the message is a reply, ID of the original message - pub reply_to_message_id: i32, + #[serde(serialize_with = "crate::types::serialize_reply_to_message_id")] + pub reply_to_message_id: MessageId, /// Pass _True_, if the message should be sent even if the specified replied-to message is not found pub allow_sending_without_reply: bool, /// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user. diff --git a/src/payloads/send_poll.rs b/src/payloads/send_poll.rs index 920ddad0..bdc1f7f7 100644 --- a/src/payloads/send_poll.rs +++ b/src/payloads/send_poll.rs @@ -3,7 +3,9 @@ use chrono::{DateTime, Utc}; use serde::Serialize; -use crate::types::{Message, MessageEntity, ParseMode, PollType, Recipient, ReplyMarkup}; +use crate::types::{ + Message, MessageEntity, MessageId, ParseMode, PollType, Recipient, ReplyMarkup, +}; impl_payload! { /// Use this method to send phone contacts. On success, the sent [`Message`] is returned. @@ -51,7 +53,8 @@ impl_payload! { /// Protects the contents of sent messages from forwarding and saving pub protect_content: bool, /// If the message is a reply, ID of the original message - pub reply_to_message_id: i32, + #[serde(serialize_with = "crate::types::serialize_reply_to_message_id")] + pub reply_to_message_id: MessageId, /// Pass _True_, if the message should be sent even if the specified replied-to message is not found pub allow_sending_without_reply: bool, /// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user. diff --git a/src/payloads/send_venue.rs b/src/payloads/send_venue.rs index bb6da175..d368aede 100644 --- a/src/payloads/send_venue.rs +++ b/src/payloads/send_venue.rs @@ -2,7 +2,7 @@ use serde::Serialize; -use crate::types::{Message, Recipient, ReplyMarkup}; +use crate::types::{Message, MessageId, Recipient, ReplyMarkup}; impl_payload! { /// Use this method to send information about a venue. On success, the sent [`Message`] is returned. @@ -40,7 +40,8 @@ impl_payload! { /// Protects the contents of sent messages from forwarding and saving pub protect_content: bool, /// If the message is a reply, ID of the original message - pub reply_to_message_id: i32, + #[serde(serialize_with = "crate::types::serialize_reply_to_message_id")] + pub reply_to_message_id: MessageId, /// Pass _True_, if the message should be sent even if the specified replied-to message is not found pub allow_sending_without_reply: bool, /// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user. diff --git a/src/payloads/send_video.rs b/src/payloads/send_video.rs index 1510cbf1..f267cbf3 100644 --- a/src/payloads/send_video.rs +++ b/src/payloads/send_video.rs @@ -2,7 +2,9 @@ use serde::Serialize; -use crate::types::{InputFile, Message, MessageEntity, ParseMode, Recipient, ReplyMarkup}; +use crate::types::{ + InputFile, Message, MessageEntity, MessageId, ParseMode, Recipient, ReplyMarkup, +}; impl_payload! { @[multipart = video, thumb] @@ -48,7 +50,8 @@ impl_payload! { /// Protects the contents of sent messages from forwarding and saving pub protect_content: bool, /// If the message is a reply, ID of the original message - pub reply_to_message_id: i32, + #[serde(serialize_with = "crate::types::serialize_reply_to_message_id")] + pub reply_to_message_id: MessageId, /// Pass _True_, if the message should be sent even if the specified replied-to message is not found pub allow_sending_without_reply: bool, /// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user. diff --git a/src/payloads/send_video_note.rs b/src/payloads/send_video_note.rs index 78892cee..2c1e4484 100644 --- a/src/payloads/send_video_note.rs +++ b/src/payloads/send_video_note.rs @@ -2,7 +2,7 @@ use serde::Serialize; -use crate::types::{InputFile, Message, Recipient, ReplyMarkup}; +use crate::types::{InputFile, Message, MessageId, Recipient, ReplyMarkup}; impl_payload! { @[multipart = video_note, thumb] @@ -36,7 +36,8 @@ impl_payload! { /// Protects the contents of sent messages from forwarding and saving pub protect_content: bool, /// If the message is a reply, ID of the original message - pub reply_to_message_id: i32, + #[serde(serialize_with = "crate::types::serialize_reply_to_message_id")] + pub reply_to_message_id: MessageId, /// Pass _True_, if the message should be sent even if the specified replied-to message is not found pub allow_sending_without_reply: bool, /// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user. diff --git a/src/payloads/send_voice.rs b/src/payloads/send_voice.rs index 8b3865b2..e1cbb888 100644 --- a/src/payloads/send_voice.rs +++ b/src/payloads/send_voice.rs @@ -2,7 +2,9 @@ use serde::Serialize; -use crate::types::{InputFile, Message, MessageEntity, ParseMode, Recipient, ReplyMarkup}; +use crate::types::{ + InputFile, Message, MessageEntity, MessageId, ParseMode, Recipient, ReplyMarkup, +}; impl_payload! { @[multipart = voice] @@ -37,7 +39,8 @@ impl_payload! { /// [silently]: https://telegram.org/blog/channels-2-0#silent-messages pub disable_notification: bool, /// If the message is a reply, ID of the original message - pub reply_to_message_id: i32, + #[serde(serialize_with = "crate::types::serialize_reply_to_message_id")] + pub reply_to_message_id: MessageId, /// Pass _True_, if the message should be sent even if the specified replied-to message is not found pub allow_sending_without_reply: bool, /// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user. diff --git a/src/payloads/set_game_score.rs b/src/payloads/set_game_score.rs index 65e7412e..eb34ed04 100644 --- a/src/payloads/set_game_score.rs +++ b/src/payloads/set_game_score.rs @@ -2,7 +2,7 @@ use serde::Serialize; -use crate::types::{Message, UserId}; +use crate::types::{Message, MessageId, UserId}; impl_payload! { /// Use this method to set the score of the specified user in a game. On success, returns the edited [`Message`]. Returns an error, if the new score is not greater than the user's current score in the chat and force is False. @@ -20,7 +20,8 @@ impl_payload! { /// Unique identifier for the target chat pub chat_id: u32, /// Identifier of the message to edit - pub message_id: i64, + #[serde(flatten)] + pub message_id: MessageId, } optional { /// Pass True, if the high score is allowed to decrease. This can be useful when fixing mistakes or banning cheaters diff --git a/src/payloads/stop_message_live_location.rs b/src/payloads/stop_message_live_location.rs index 8f454fb1..970fc87c 100644 --- a/src/payloads/stop_message_live_location.rs +++ b/src/payloads/stop_message_live_location.rs @@ -2,7 +2,7 @@ use serde::Serialize; -use crate::types::{Message, Recipient, ReplyMarkup}; +use crate::types::{Message, MessageId, Recipient, ReplyMarkup}; impl_payload! { /// Use this method to edit live location messages. A location can be edited until its live_period expires or editing is explicitly disabled by a call to [`StopMessageLiveLocation`]. On success, the edited Message is returned. @@ -17,7 +17,8 @@ impl_payload! { /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) pub chat_id: Recipient [into], /// Identifier of the message to edit - pub message_id: i32, + #[serde(flatten)] + pub message_id: MessageId, /// Latitude of new location pub latitude: f64, /// Longitude of new location diff --git a/src/payloads/stop_poll.rs b/src/payloads/stop_poll.rs index ba884397..05ab001d 100644 --- a/src/payloads/stop_poll.rs +++ b/src/payloads/stop_poll.rs @@ -2,7 +2,7 @@ use serde::Serialize; -use crate::types::{InlineKeyboardMarkup, Poll, Recipient}; +use crate::types::{InlineKeyboardMarkup, MessageId, Poll, Recipient}; impl_payload! { /// Use this method to stop a poll which was sent by the bot. On success, the stopped Poll with the final results is returned. @@ -12,7 +12,8 @@ impl_payload! { /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`). pub chat_id: Recipient [into], /// Identifier of the message to edit - pub message_id: i32, + #[serde(flatten)] + pub message_id: MessageId, } optional { /// A JSON-serialized object for an [inline keyboard]. diff --git a/src/payloads/unpin_chat_message.rs b/src/payloads/unpin_chat_message.rs index f5576134..94771ea0 100644 --- a/src/payloads/unpin_chat_message.rs +++ b/src/payloads/unpin_chat_message.rs @@ -2,7 +2,7 @@ use serde::Serialize; -use crate::types::{Recipient, True}; +use crate::types::{MessageId, Recipient, True}; impl_payload! { /// Use this method to remove a message from the list of pinned messages in a chat. If the chat is not a private chat, the bot must be an administrator in the chat for this to work and must have the 'can_pin_messages' admin right in a supergroup or 'can_edit_messages' admin right in a channel. Returns _True_ on success. @@ -14,7 +14,8 @@ impl_payload! { } optional { /// Identifier of a message to unpin. If not specified, the most recent pinned message (by sending date) will be unpinned. - pub message_id: i32, + #[serde(flatten)] + pub message_id: MessageId, } } } diff --git a/src/requests/requester.rs b/src/requests/requester.rs index b18a825c..b863cb06 100644 --- a/src/requests/requester.rs +++ b/src/requests/requester.rs @@ -111,7 +111,7 @@ pub trait Requester { &self, chat_id: C, from_chat_id: F, - message_id: i32, + message_id: MessageId, ) -> Self::ForwardMessage where C: Into, @@ -120,7 +120,12 @@ pub trait Requester { type CopyMessage: Request; /// For Telegram documentation see [`CopyMessage`]. - fn copy_message(&self, chat_id: C, from_chat_id: F, message_id: i32) -> Self::CopyMessage + fn copy_message( + &self, + chat_id: C, + from_chat_id: F, + message_id: MessageId, + ) -> Self::CopyMessage where C: Into, F: Into; @@ -195,7 +200,7 @@ pub trait Requester { fn edit_message_live_location( &self, chat_id: C, - message_id: i32, + message_id: MessageId, latitude: f64, longitude: f64, ) -> Self::EditMessageLiveLocation @@ -223,7 +228,7 @@ pub trait Requester { fn stop_message_live_location( &self, chat_id: C, - message_id: i32, + message_id: MessageId, latitude: f64, longitude: f64, ) -> Self::StopMessageLiveLocation @@ -485,7 +490,7 @@ pub trait Requester { type PinChatMessage: Request; /// For Telegram documentation see [`PinChatMessage`]. - fn pin_chat_message(&self, chat_id: C, message_id: i32) -> Self::PinChatMessage + fn pin_chat_message(&self, chat_id: C, message_id: MessageId) -> Self::PinChatMessage where C: Into; @@ -639,7 +644,7 @@ pub trait Requester { fn edit_message_text( &self, chat_id: C, - message_id: i32, + message_id: MessageId, text: T, ) -> Self::EditMessageText where @@ -661,7 +666,11 @@ pub trait Requester { type EditMessageCaption: Request; /// For Telegram documentation see [`EditMessageCaption`]. - fn edit_message_caption(&self, chat_id: C, message_id: i32) -> Self::EditMessageCaption + fn edit_message_caption( + &self, + chat_id: C, + message_id: MessageId, + ) -> Self::EditMessageCaption where C: Into; @@ -681,7 +690,7 @@ pub trait Requester { fn edit_message_media( &self, chat_id: C, - message_id: i32, + message_id: MessageId, media: InputMedia, ) -> Self::EditMessageMedia where @@ -704,7 +713,7 @@ pub trait Requester { fn edit_message_reply_markup( &self, chat_id: C, - message_id: i32, + message_id: MessageId, ) -> Self::EditMessageReplyMarkup where C: Into; @@ -725,14 +734,14 @@ pub trait Requester { type StopPoll: Request; /// For Telegram documentation see [`StopPoll`]. - fn stop_poll(&self, chat_id: C, message_id: i32) -> Self::StopPoll + fn stop_poll(&self, chat_id: C, message_id: MessageId) -> Self::StopPoll where C: Into; type DeleteMessage: Request; /// For Telegram documentation see [`DeleteMessage`]. - fn delete_message(&self, chat_id: C, message_id: i32) -> Self::DeleteMessage + fn delete_message(&self, chat_id: C, message_id: MessageId) -> Self::DeleteMessage where C: Into; @@ -907,7 +916,7 @@ pub trait Requester { user_id: UserId, score: u64, chat_id: u32, - message_id: i64, + message_id: MessageId, ) -> Self::SetGameScore; type SetGameScoreInline: Request; diff --git a/src/types.rs b/src/types.rs index 6f35de8a..2ff4585a 100644 --- a/src/types.rs +++ b/src/types.rs @@ -86,6 +86,7 @@ pub use reply_keyboard_remove::*; pub use reply_markup::*; pub use response_parameters::*; pub use sent_web_app_message::*; +use serde::Serialize; pub use shipping_address::*; pub use shipping_option::*; pub use shipping_query::*; @@ -405,3 +406,13 @@ pub(crate) mod duration_secs { } } } + +pub(crate) fn serialize_reply_to_message_id( + this: &Option, + serializer: S, +) -> Result +where + S: serde::Serializer, +{ + this.map(|MessageId(id)| id).serialize(serializer) +} diff --git a/src/types/message.rs b/src/types/message.rs index 54da04d9..6edc9451 100644 --- a/src/types/message.rs +++ b/src/types/message.rs @@ -1206,7 +1206,7 @@ impl Message { /// Returns `None` for private chats (i.e.: DMs) and private groups (not /// supergroups). #[must_use] - pub fn comment_url(&self, comment_id: i32) -> Option { + pub fn comment_url(&self, comment_id: MessageId) -> Option { Self::comment_url_of(self.chat.id, self.chat.username(), self.id, comment_id) } @@ -1228,11 +1228,11 @@ impl Message { pub fn comment_url_of( channel_id: ChatId, channel_username: Option<&str>, - post_id: i32, - comment_id: i32, + post_id: MessageId, + comment_id: MessageId, ) -> Option { Self::url_of(channel_id, channel_username, post_id).map(|mut url| { - url.set_query(Some(&format!("comment={comment_id}"))); + url.set_query(Some(&format!("comment={}", comment_id.0))); url }) } @@ -1249,7 +1249,7 @@ impl Message { /// Returns `None` for private chats (i.e.: DMs) and private groups (not /// supergroups). #[must_use] - pub fn url_in_thread(&self, thread_starter_msg_id: i32) -> Option { + pub fn url_in_thread(&self, thread_starter_msg_id: MessageId) -> Option { Self::url_in_thread_of( self.chat.id, self.chat.username(), diff --git a/src/types/message_id.rs b/src/types/message_id.rs index 88a90902..27e1f91c 100644 --- a/src/types/message_id.rs +++ b/src/types/message_id.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; /// A unique message identifier. -#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct MessageId(#[serde(rename = "message_id")] pub i32); #[cfg(test)] diff --git a/src/types/update.rs b/src/types/update.rs index 0ca68c3e..2d0ac5e6 100644 --- a/src/types/update.rs +++ b/src/types/update.rs @@ -297,7 +297,7 @@ impl Serialize for UpdateKind { mod test { use crate::types::{ Chat, ChatId, ChatKind, ChatPrivate, MediaKind, MediaText, Message, MessageCommon, - MessageKind, Update, UpdateKind, User, UserId, + MessageKind, Update, UpdateKind, User, UserId, MessageId }; use chrono::{DateTime, NaiveDateTime, Utc}; @@ -334,7 +334,7 @@ mod test { id: 892_252_934, kind: UpdateKind::Message(Message { via_bot: None, - id: 6557, + id: MessageId(6557), date, chat: Chat { id: ChatId(218_485_655), From 13e5ed8fb4ef4ddb60d662c71f0792620fd7476f Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 29 Sep 2022 13:32:36 +0400 Subject: [PATCH 3/5] Fix `MessageId` deserialization --- src/types/message_id.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/types/message_id.rs b/src/types/message_id.rs index 27e1f91c..31cbd20c 100644 --- a/src/types/message_id.rs +++ b/src/types/message_id.rs @@ -2,7 +2,25 @@ use serde::{Deserialize, Serialize}; /// A unique message identifier. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub struct MessageId(#[serde(rename = "message_id")] pub i32); +#[serde(from = "MessageIdRaw", into = "MessageIdRaw")] +pub struct MessageId(pub i32); + +#[derive(Serialize, Deserialize)] +struct MessageIdRaw { + message_id: i32, +} + +impl From for MessageId { + fn from(MessageIdRaw { message_id }: MessageIdRaw) -> Self { + MessageId(message_id) + } +} + +impl From for MessageIdRaw { + fn from(MessageId(message_id): MessageId) -> Self { + MessageIdRaw { message_id } + } +} #[cfg(test)] mod tests { From 0f08fd6cdbe50d7d63354c404e9da9bc2d6d862b Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 29 Sep 2022 13:33:11 +0400 Subject: [PATCH 4/5] fmt? --- src/types/update.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/update.rs b/src/types/update.rs index 2d0ac5e6..0fb34e6e 100644 --- a/src/types/update.rs +++ b/src/types/update.rs @@ -297,7 +297,7 @@ impl Serialize for UpdateKind { mod test { use crate::types::{ Chat, ChatId, ChatKind, ChatPrivate, MediaKind, MediaText, Message, MessageCommon, - MessageKind, Update, UpdateKind, User, UserId, MessageId + MessageId, MessageKind, Update, UpdateKind, User, UserId, }; use chrono::{DateTime, NaiveDateTime, Utc}; From 57d08938e4ebf3ddf628dd1d13768158bf768005 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sat, 1 Oct 2022 17:04:31 +0400 Subject: [PATCH 5/5] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1861a0f..7a0a335c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,9 +21,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Request` now requires `Self: IntoFuture` - There is no need for `AutoSend` anymore - MSRV (Minimal Supported Rust Version) was bumped from `1.58.0` to `1.64.0` +- Message id parameters and fields now use `MessageId` type instead of `i32` ([#254][pr254]) - Refactored `Sticker` and related types ([#251][pr251]) [pr253]: https://github.com/teloxide/teloxide-core/pull/253 +[pr254]: https://github.com/teloxide/teloxide-core/pull/254 ### Removed