More types + some fixes

This commit is contained in:
LasterAlex 2024-08-30 09:05:49 +03:00
parent cc0f2a73a8
commit fc7abb70d5
No known key found for this signature in database
3 changed files with 91 additions and 16 deletions

View file

@ -1826,6 +1826,14 @@ impl IntoIterator for Message {
} }
} }
/// Implemented for syntax sugar, see issue <https://github.com/teloxide/teloxide/issues/1143>
#[allow(clippy::from_over_into)]
impl Into<MessageId> for Message {
fn into(self) -> MessageId {
self.id
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use chrono::DateTime; use chrono::DateTime;

View file

@ -2,15 +2,19 @@
//! //!
//! [`Bot`]: crate::Bot //! [`Bot`]: crate::Bot
use crate::{prelude::*, types::*}; use crate::{prelude::*, types::*};
use teloxide_core::{payloads::*, requests::JsonRequest};
use std::collections::HashSet; use std::collections::HashSet;
/// Adds useful manipulations with [`Message`] structs
///
/// [`Message`]: crate::types::Message
pub trait BotMessagesExt { pub trait BotMessagesExt {
/// This function is the same as [`Bot::forward_messages`], /// This function is the same as [`Bot::forward_messages`],
/// but can take in [`Message`], including just one. /// but can take in [`Message`], including just one.
/// ///
/// [`Bot::forward_messages`]: crate::Bot::forward_messages /// [`Bot::forward_messages`]: crate::Bot::forward_messages
/// [`Message`]: crate::types::Message /// [`Message`]: crate::types::Message
fn forward<C, M>(&self, to_chat_id: C, messages: M) -> <Bot as Requester>::ForwardMessages fn forward<C, M>(&self, to_chat_id: C, messages: M) -> JsonRequest<ForwardMessages>
where where
C: Into<Recipient>, C: Into<Recipient>,
M: IntoIterator<Item = Message>; M: IntoIterator<Item = Message>;
@ -20,7 +24,7 @@ pub trait BotMessagesExt {
/// ///
/// [`Bot::copy_messages`]: crate::Bot::copy_messages /// [`Bot::copy_messages`]: crate::Bot::copy_messages
/// [`Message`]: crate::types::Message /// [`Message`]: crate::types::Message
fn copy<C, M>(&self, to_chat_id: C, messages: M) -> <Bot as Requester>::CopyMessages fn copy<C, M>(&self, to_chat_id: C, messages: M) -> JsonRequest<CopyMessages>
where where
C: Into<Recipient>, C: Into<Recipient>,
M: IntoIterator<Item = Message>; M: IntoIterator<Item = Message>;
@ -30,7 +34,7 @@ pub trait BotMessagesExt {
/// ///
/// [`Bot::delete_messages`]: crate::Bot::delete_messages /// [`Bot::delete_messages`]: crate::Bot::delete_messages
/// [`Message`]: crate::types::Message /// [`Message`]: crate::types::Message
fn delete<M>(&self, messages: M) -> <Bot as Requester>::DeleteMessages fn delete<M>(&self, messages: M) -> JsonRequest<DeleteMessages>
where where
M: IntoIterator<Item = Message>; M: IntoIterator<Item = Message>;
} }
@ -58,7 +62,7 @@ where
} }
impl BotMessagesExt for Bot { impl BotMessagesExt for Bot {
fn forward<C, M>(&self, to_chat_id: C, messages: M) -> <Bot as Requester>::ForwardMessages fn forward<C, M>(&self, to_chat_id: C, messages: M) -> JsonRequest<ForwardMessages>
where where
C: Into<Recipient>, C: Into<Recipient>,
M: IntoIterator<Item = Message>, M: IntoIterator<Item = Message>,
@ -67,7 +71,7 @@ impl BotMessagesExt for Bot {
self.forward_messages(to_chat_id, from_chat_id, message_ids) self.forward_messages(to_chat_id, from_chat_id, message_ids)
} }
fn copy<C, M>(&self, to_chat_id: C, messages: M) -> <Bot as Requester>::CopyMessages fn copy<C, M>(&self, to_chat_id: C, messages: M) -> JsonRequest<CopyMessages>
where where
C: Into<Recipient>, C: Into<Recipient>,
M: IntoIterator<Item = Message>, M: IntoIterator<Item = Message>,
@ -76,7 +80,7 @@ impl BotMessagesExt for Bot {
self.copy_messages(to_chat_id, from_chat_id, message_ids) self.copy_messages(to_chat_id, from_chat_id, message_ids)
} }
fn delete<M>(&self, messages: M) -> <Bot as Requester>::DeleteMessages fn delete<M>(&self, messages: M) -> JsonRequest<DeleteMessages>
where where
M: IntoIterator<Item = Message>, M: IntoIterator<Item = Message>,
{ {
@ -86,14 +90,14 @@ impl BotMessagesExt for Bot {
} }
#[cfg(test)] #[cfg(test)]
mod tests { pub(crate) mod tests {
use std::ops::Deref; use std::ops::Deref;
use chrono::DateTime; use chrono::DateTime;
use super::*; use super::*;
fn make_message(chat_id: ChatId, message_id: MessageId) -> Message { pub(crate) fn make_message(chat_id: ChatId, message_id: MessageId) -> Message {
let timestamp = 1_569_518_829; let timestamp = 1_569_518_829;
let date = DateTime::from_timestamp(timestamp, 0).unwrap(); let date = DateTime::from_timestamp(timestamp, 0).unwrap();
Message { Message {
@ -241,4 +245,12 @@ mod tests {
let message = make_message(ChatId(1), MessageId(1)); let message = make_message(ChatId(1), MessageId(1));
assert_eq!(message.clone().into_iter().next(), Some(message)); assert_eq!(message.clone().into_iter().next(), Some(message));
} }
#[test]
fn message_to_message_id() {
// Just to make sure message still can be in Into<MessageId>
let message = make_message(ChatId(1), MessageId(1));
let message_id: MessageId = message.into();
assert_eq!(message_id, MessageId(1));
}
} }

View file

@ -1,8 +1,13 @@
//! Additions to [`JsonRequest`]. //! Additions to [`JsonRequest`] and [`MultipartRequest`].
//! //!
//! [`JsonRequest`]: teloxide_core::requests::JsonRequest //! [`JsonRequest`]: teloxide_core::requests::JsonRequest
//! [`MultipartRequest`]: teloxide_core::requests::MultipartRequest
use teloxide_core::{payloads::*, prelude::Requester, types::*, Bot}; use teloxide_core::{
payloads::*,
requests::{JsonRequest, MultipartRequest},
types::*,
};
macro_rules! impl_request_reply_ext { macro_rules! impl_request_reply_ext {
($($t:ty),*) => { ($($t:ty),*) => {
@ -24,12 +29,12 @@ macro_rules! impl_request_link_preview_ext {
($($t:ty),*) => { ($($t:ty),*) => {
$( $(
impl RequestLinkPreviewExt for $t { impl RequestLinkPreviewExt for $t {
fn disable_link_preview(self) -> Self fn disable_link_preview(self, is_disabled: bool) -> Self
where where
Self: Sized Self: Sized
{ {
let link_preview_options = LinkPreviewOptions { let link_preview_options = LinkPreviewOptions {
is_disabled: true, is_disabled,
url: None, url: None,
prefer_small_media: false, prefer_small_media: false,
prefer_large_media: false, prefer_large_media: false,
@ -42,25 +47,57 @@ macro_rules! impl_request_link_preview_ext {
}; };
} }
/// Adds `.reply_to(message_id)` to requests
pub trait RequestReplyExt { pub trait RequestReplyExt {
/// Replaces `.reply_parameters(ReplyParameters::new(msg.id))`
/// with `.reply_to(msg.id)` or `.reply_to(msg)`
fn reply_to<M>(self, message_id: M) -> Self fn reply_to<M>(self, message_id: M) -> Self
where where
M: Into<MessageId>, M: Into<MessageId>,
Self: Sized; Self: Sized;
} }
/// Adds `.disable_link_preview(is_disabled)` to requests
pub trait RequestLinkPreviewExt { pub trait RequestLinkPreviewExt {
fn disable_link_preview(self) -> Self /// Replaces
/// `.link_preview_options(LinkPreviewOptions {
/// is_disabled: true,
/// url: None,
/// prefer_small_media: false,
/// prefer_large_media: false,
/// show_above_text: false
/// };)`
///
/// With `.disable_link_preview(true)`
fn disable_link_preview(self, is_disabled: bool) -> Self
where where
Self: Sized; Self: Sized;
} }
impl_request_reply_ext! { impl_request_reply_ext! {
<Bot as Requester>::SendMessage JsonRequest<SendDice>,
JsonRequest<SendInvoice>,
JsonRequest<SendPoll>,
JsonRequest<SendContact>,
JsonRequest<SendGame>,
JsonRequest<SendVenue>,
JsonRequest<SendLocation>,
JsonRequest<CopyMessage>,
JsonRequest<SendMessage>,
MultipartRequest<SendSticker>,
MultipartRequest<SendMediaGroup>,
MultipartRequest<SendAnimation>,
MultipartRequest<SendVideoNote>,
MultipartRequest<SendVideo>,
MultipartRequest<SendDocument>,
MultipartRequest<SendAudio>,
MultipartRequest<SendVoice>,
MultipartRequest<SendPhoto>
} }
impl_request_link_preview_ext! { impl_request_link_preview_ext! {
<Bot as Requester>::SendMessage JsonRequest<SendMessage>,
JsonRequest<EditMessageText>
} }
#[cfg(test)] #[cfg(test)]
@ -73,6 +110,7 @@ mod tests {
#[test] #[test]
fn test_reply_to() { fn test_reply_to() {
let bot = Bot::new("TOKEN"); let bot = Bot::new("TOKEN");
let real_reply_req = bot let real_reply_req = bot
.send_message(ChatId(1234), "test") .send_message(ChatId(1234), "test")
.reply_parameters(ReplyParameters::new(MessageId(1))); .reply_parameters(ReplyParameters::new(MessageId(1)));
@ -81,6 +119,22 @@ mod tests {
assert_eq!(real_reply_req.deref(), sugar_reply_req.deref()) assert_eq!(real_reply_req.deref(), sugar_reply_req.deref())
} }
#[test]
fn test_reply_to_multipart() {
let bot = Bot::new("TOKEN");
let document = InputFile::memory("hello world!");
let real_reply_req = bot
.send_document(ChatId(1234), document.clone())
.reply_parameters(ReplyParameters::new(MessageId(1)));
let sugar_reply_req = bot.send_document(ChatId(1234), document).reply_to(MessageId(1));
assert_eq!(
real_reply_req.deref().reply_parameters,
sugar_reply_req.deref().reply_parameters
)
}
#[test] #[test]
fn test_disable_link_preview() { fn test_disable_link_preview() {
let link_preview_options = LinkPreviewOptions { let link_preview_options = LinkPreviewOptions {
@ -91,9 +145,10 @@ mod tests {
show_above_text: false, show_above_text: false,
}; };
let bot = Bot::new("TOKEN"); let bot = Bot::new("TOKEN");
let real_link_req = let real_link_req =
bot.send_message(ChatId(1234), "test").link_preview_options(link_preview_options); bot.send_message(ChatId(1234), "test").link_preview_options(link_preview_options);
let sugar_link_req = bot.send_message(ChatId(1234), "test").disable_link_preview(); let sugar_link_req = bot.send_message(ChatId(1234), "test").disable_link_preview(true);
assert_eq!(real_link_req.deref(), sugar_link_req.deref()) assert_eq!(real_link_req.deref(), sugar_link_req.deref())
} }