From 5b328105fa306be3dcb803451cd802a615af4c52 Mon Sep 17 00:00:00 2001 From: Waffle Date: Tue, 26 Jan 2021 13:20:08 +0300 Subject: [PATCH 1/5] Sticker related fixes - Rename `sticker_type.rs` => `input_sticker.rs` (after the contained type) - Make `create_new_sticker_set` multipart - Replace CreateNewStickerSet::{png,tgs}_sticker with `<_>::sticker` - Fix GetStickerSet return type - Revert some previous InputSticker changes: make the variants tuple structsm remove constructors --- src/bot/api.rs | 5 ++-- src/local_macros.rs | 4 +-- src/payloads/create_new_sticker_set.rs | 13 +++++---- src/payloads/get_sticker_set.rs | 4 +-- src/requests/requester.rs | 1 + src/types.rs | 4 +-- .../{sticker_type.rs => input_sticker.rs} | 27 +++---------------- 7 files changed, 20 insertions(+), 38 deletions(-) rename src/types/{sticker_type.rs => input_sticker.rs} (64%) diff --git a/src/bot/api.rs b/src/bot/api.rs index e96f9216..86997994 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -765,13 +765,14 @@ impl Requester for Bot { ) } - type CreateNewStickerSet = JsonRequest; + type CreateNewStickerSet = MultipartRequest; fn create_new_sticker_set( &self, user_id: i32, name: N, title: T, + sticker: InputSticker, emojis: E, ) -> Self::CreateNewStickerSet where @@ -781,7 +782,7 @@ impl Requester for Bot { { Self::CreateNewStickerSet::new( self.clone(), - payloads::CreateNewStickerSet::new(user_id, name, title, emojis), + payloads::CreateNewStickerSet::new(user_id, name, title, sticker, emojis), ) } diff --git a/src/local_macros.rs b/src/local_macros.rs index fb528f5d..a2549a00 100644 --- a/src/local_macros.rs +++ b/src/local_macros.rs @@ -924,11 +924,11 @@ macro_rules! requester_forward { (@method create_new_sticker_set $body:ident $ty:ident) => { type CreateNewStickerSet = $ty![CreateNewStickerSet]; - fn create_new_sticker_set(&self, user_id: i32, name: N, title: T, emojis: E) -> Self::CreateNewStickerSet where N: Into, + fn create_new_sticker_set(&self, user_id: i32, name: N, title: T, sticker: InputSticker, emojis: E) -> Self::CreateNewStickerSet where N: Into, T: Into, E: Into { let this = self; - $body!(create_new_sticker_set this (user_id: i32, name: N, title: T, emojis: E)) + $body!(create_new_sticker_set this (user_id: i32, name: N, title: T, sticker: InputSticker, emojis: E)) } }; (@method add_sticker_to_set $body:ident $ty:ident) => { diff --git a/src/payloads/create_new_sticker_set.rs b/src/payloads/create_new_sticker_set.rs index 2504ce00..ce2fc4bb 100644 --- a/src/payloads/create_new_sticker_set.rs +++ b/src/payloads/create_new_sticker_set.rs @@ -3,7 +3,7 @@ // edit `cg` instead. use serde::Serialize; -use crate::types::{InputFile, MaskPosition, True}; +use crate::types::{InputSticker, MaskPosition, True}; impl_payload! { /// Use this method to create a new sticker set owned by a user. The bot will be able to edit the sticker set thus created. You must use exactly one of the fields _png\_sticker_ or _tgs\_sticker_. Returns _True_ on success. @@ -16,16 +16,15 @@ impl_payload! { pub name: String [into], /// Sticker set title, 1-64 characters pub title: String [into], + /// **PNG** or **TGS** image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px. Pass a _file\_id_ as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. [More info on Sending Files »] + /// + /// [More info on Sending Files »]: crate::types::InputFile + #[serde(flatten)] + pub sticker: InputSticker, /// One or more emoji corresponding to the sticker pub emojis: String [into], } optional { - /// **PNG** image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px. Pass a _file\_id_ as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. [More info on Sending Files »] - /// - /// [More info on Sending Files »]: crate::types::InputFile - pub png_sticker: InputFile, - /// **TGS** animation with the sticker, uploaded using multipart/form-data. See https://core.telegram.org/animated_stickers#technical-requirements for technical requirements - pub tgs_sticker: InputFile, /// Pass _True_, if a set of mask stickers should be created pub contains_masks: bool, /// A JSON-serialized object for position where the mask should be placed on faces diff --git a/src/payloads/get_sticker_set.rs b/src/payloads/get_sticker_set.rs index a1b74857..96c96f7b 100644 --- a/src/payloads/get_sticker_set.rs +++ b/src/payloads/get_sticker_set.rs @@ -3,12 +3,12 @@ // edit `cg` instead. use serde::Serialize; -use crate::types::True; +use crate::types::StickerSet; impl_payload! { /// Use this method to get a sticker set. On success, a StickerSet object is returned. #[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize)] - pub GetStickerSet (GetStickerSetSetters) => True { + pub GetStickerSet (GetStickerSetSetters) => StickerSet { required { /// Name of the sticker set pub name: String [into], diff --git a/src/requests/requester.rs b/src/requests/requester.rs index e8a32943..b8afc2e4 100644 --- a/src/requests/requester.rs +++ b/src/requests/requester.rs @@ -617,6 +617,7 @@ pub trait Requester { user_id: i32, name: N, title: T, + sticker: InputSticker, emojis: E, ) -> Self::CreateNewStickerSet where diff --git a/src/types.rs b/src/types.rs index 05430052..d352caac 100644 --- a/src/types.rs +++ b/src/types.rs @@ -50,6 +50,7 @@ pub use inline_query_result_voice::*; pub use input_file::*; pub use input_media::*; pub use input_message_content::*; +pub use input_sticker::*; pub use invoice::*; pub use keyboard_button::*; pub use keyboard_button_poll_type::*; @@ -80,7 +81,6 @@ pub use shipping_option::*; pub use shipping_query::*; pub use sticker::*; pub use sticker_set::*; -pub use sticker_type::*; pub use successful_payment::*; pub use target_message::*; pub use unit_false::*; @@ -120,6 +120,7 @@ mod inline_keyboard_markup; mod input_file; mod input_media; mod input_message_content; +mod input_sticker; mod invoice; mod keyboard_button; mod keyboard_button_poll_type; @@ -147,7 +148,6 @@ mod shipping_option; mod shipping_query; mod sticker; mod sticker_set; -mod sticker_type; mod successful_payment; mod target_message; mod unit_false; diff --git a/src/types/sticker_type.rs b/src/types/input_sticker.rs similarity index 64% rename from src/types/sticker_type.rs rename to src/types/input_sticker.rs index d15a4812..8f765495 100644 --- a/src/types/sticker_type.rs +++ b/src/types/input_sticker.rs @@ -4,7 +4,6 @@ use crate::types::InputFile; /// Sticker file that may be uploaded to telegram. #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize)] -#[serde(untagged)] pub enum InputSticker { /// PNG image with the sticker, must be up to 512 kilobytes in size, /// dimensions must not exceed 512px, and either width or height must be @@ -20,30 +19,12 @@ pub enum InputSticker { /// [`InputFile::FileId`]: crate::types::InputFile::FileId /// /// [More info on Sending Files »]: https://core.telegram.org/bots/api#sending-files - Png { png_sticker: InputFile }, + #[serde(rename = "png_sticker")] + Png(InputFile), /// TGS animation with the sticker, uploaded using multipart/form-data. /// /// See https://core.telegram.org/animated_stickers#technical-requirements for technical requirements - Tgs { tgs_sticker: InputFile }, -} - -impl InputSticker { - /// Create png-`InputSticker`. - /// - /// See [`InputSticker::Png`] for more - /// - /// [`InputSticker::Png`]: crate::types::InputSticker::Png - pub fn png(png_sticker: InputFile) -> Self { - Self::Png { png_sticker } - } - - /// Create tgs-`InputSticker`. - /// - /// See [`InputSticker::Tgs`] for more - /// - /// [`InputSticker::Tgs`]: crate::types::InputSticker::Tgs - pub fn tgs(tgs_sticker: InputFile) -> Self { - Self::Tgs { tgs_sticker } - } + #[serde(rename = "tgs_sticker")] + Tgs(InputFile), } From bfef7f3c5d45a366ab3aa1054e6543d1198791c5 Mon Sep 17 00:00:00 2001 From: Waffle Date: Tue, 26 Jan 2021 13:43:34 +0300 Subject: [PATCH 2/5] fix `self_info` example --- examples/self_info.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/self_info.rs b/examples/self_info.rs index 78678e9f..78b2cec4 100644 --- a/examples/self_info.rs +++ b/examples/self_info.rs @@ -15,7 +15,7 @@ async fn main() -> Result<(), Box> { let me = bot.get_me().await?; - bot.send_dice(chat_id, DiceEmoji::Dice).await?; + bot.send_dice(chat_id).emoji(DiceEmoji::Dice).await?; bot.send_message(chat_id, format!("Hi, my name is **{}** 👋", me.first_name)) .await?; From a80ff92abac067fa7857c8ce70df41e35745dce0 Mon Sep 17 00:00:00 2001 From: Waffle Date: Tue, 26 Jan 2021 13:58:51 +0300 Subject: [PATCH 3/5] make `get_me` return `Me` --- src/adaptors/cache_me.rs | 26 +++++++++++++------------- src/payloads/get_me.rs | 4 ++-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/adaptors/cache_me.rs b/src/adaptors/cache_me.rs index 539004bd..541c9d42 100644 --- a/src/adaptors/cache_me.rs +++ b/src/adaptors/cache_me.rs @@ -11,7 +11,7 @@ use once_cell::sync::OnceCell; use crate::{ payloads::GetMe, requests::{HasPayload, Request, Requester}, - types::{ChatId, User, *}, + types::{ChatId, Me, *}, }; /// `get_me` cache. @@ -20,7 +20,7 @@ use crate::{ /// response from `get_me` method. pub struct CacheMe { bot: B, - me: Arc>, + me: Arc>, } impl CacheMe { @@ -52,7 +52,7 @@ impl CacheMe { /// /// Note: internally this uses [`Arc::make_mut`] so this will **not** /// clear cache of clones of self. - pub fn clear(&mut self) -> Option { + pub fn clear(&mut self) -> Option { Arc::make_mut(&mut self.me).take() } } @@ -79,7 +79,7 @@ where fn get_me(&self) -> Self::GetMe { match self.me.get() { - Some(user) => CachedMeRequest(Inner::Ready(user.clone()), GetMe::new()), + Some(me) => CachedMeRequest(Inner::Ready(me.clone()), GetMe::new()), None => CachedMeRequest( Inner::Pending(self.bot.get_me(), Arc::clone(&self.me)), GetMe::new(), @@ -132,8 +132,8 @@ download_forward! { pub struct CachedMeRequest>(Inner, GetMe); enum Inner> { - Ready(User), - Pending(R, Arc>), + Ready(Me), + Pending(R, Arc>), } impl Request for CachedMeRequest @@ -146,7 +146,7 @@ where fn send(self) -> Self::Send { let fut = match self.0 { - Inner::Ready(user) => future::Either::Left(ok(user)), + Inner::Ready(me) => future::Either::Left(ok(me)), Inner::Pending(req, cell) => future::Either::Right(Init(req.send(), cell)), }; Send(fut) @@ -154,7 +154,7 @@ where fn send_ref(&self) -> Self::SendRef { let fut = match &self.0 { - Inner::Ready(user) => future::Either::Left(ok(user.clone())), + Inner::Ready(me) => future::Either::Left(ok(me.clone())), Inner::Pending(req, cell) => { future::Either::Right(Init(req.send_ref(), Arc::clone(cell))) } @@ -175,15 +175,15 @@ impl> HasPayload for CachedMeRequest { } } -type ReadyUser = Ready>; +type ReadyMe = Ready>; #[pin_project::pin_project] pub struct Send>( - #[pin] future::Either, Init>, + #[pin] future::Either, Init>, ); impl> Future for Send { - type Output = Result; + type Output = Result; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.project(); @@ -193,11 +193,11 @@ impl> Future for Send { #[pin_project::pin_project] pub struct SendRef>( - #[pin] future::Either, Init>, + #[pin] future::Either, Init>, ); impl> Future for SendRef { - type Output = Result; + type Output = Result; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.project(); diff --git a/src/payloads/get_me.rs b/src/payloads/get_me.rs index 8794d5a6..a47285b7 100644 --- a/src/payloads/get_me.rs +++ b/src/payloads/get_me.rs @@ -3,14 +3,14 @@ // edit `cg` instead. use serde::Serialize; -use crate::types::User; +use crate::types::Me; impl_payload! { /// A simple method for testing your bot's auth token. Requires no parameters. Returns basic information about the bot in form of a [`User`] object. /// /// [`User`]: crate::types::User #[derive(Debug, PartialEq, Eq, Hash, Default, Clone, Serialize)] - pub GetMe (GetMeSetters) => User { + pub GetMe (GetMeSetters) => Me { } } From 8807cd72282bc1a2a6d3932234392b3ca4ac7d8d Mon Sep 17 00:00:00 2001 From: Waffle Date: Tue, 26 Jan 2021 14:10:37 +0300 Subject: [PATCH 4/5] fix examples (because get_me now returns Me) --- examples/self_info.rs | 4 ++-- src/lib.rs | 7 +++++-- src/requests/request.rs | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/examples/self_info.rs b/examples/self_info.rs index 78b2cec4..5735bbb3 100644 --- a/examples/self_info.rs +++ b/examples/self_info.rs @@ -1,6 +1,6 @@ use teloxide_core::{ prelude::*, - types::{DiceEmoji, ParseMode}, + types::{DiceEmoji, Me, ParseMode}, }; #[tokio::main] @@ -13,7 +13,7 @@ async fn main() -> Result<(), Box> { .parse_mode(ParseMode::MarkdownV2) .auto_send(); - let me = bot.get_me().await?; + let Me { user: me, .. } = bot.get_me().await?; bot.send_dice(chat_id).emoji(DiceEmoji::Dice).await?; bot.send_message(chat_id, format!("Hi, my name is **{}** 👋", me.first_name)) diff --git a/src/lib.rs b/src/lib.rs index cca00141..8c557789 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,8 +25,11 @@ //! let me = bot.get_me().await?; //! //! bot.send_dice(chat_id).emoji(DiceEmoji::Dice).await?; -//! bot.send_message(chat_id, format!("Hi, my name is **{}** 👋", me.first_name)) -//! .await?; +//! bot.send_message( +//! chat_id, +//! format!("Hi, my name is **{}** 👋", me.user.first_name), +//! ) +//! .await?; //! # Ok::<_, Box>(()) }; //! ``` //! diff --git a/src/requests/request.rs b/src/requests/request.rs index 8517daa2..6ea6c5b4 100644 --- a/src/requests/request.rs +++ b/src/requests/request.rs @@ -44,7 +44,7 @@ pub trait Request: HasPayload { /// use teloxide_core::{ /// payloads::GetMe, /// requests::{JsonRequest, Request}, - /// types::User, + /// types::Me, /// Bot, /// }; /// @@ -53,7 +53,7 @@ pub trait Request: HasPayload { /// // Note: it's recommended to `Requester` instead of creating requests directly /// let method = GetMe::new(); /// let request = JsonRequest::new(bot, method); - /// let _: User = request.send().await.unwrap(); + /// let _: Me = request.send().await.unwrap(); /// # }; /// ``` fn send(self) -> Self::Send; From d663879423997eaecec08d8de3ff7566dd582b6e Mon Sep 17 00:00:00 2001 From: Waffle Date: Tue, 26 Jan 2021 14:52:50 +0300 Subject: [PATCH 5/5] fix example and add --features full to ci --- .github/workflows/ci.yml | 4 ++-- src/adaptors/auto_send.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4790ad17..939b0930 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,9 +20,9 @@ jobs: include: - rust: stable - features: "" + features: "--features full" - rust: beta - features: "" + features: "--features full" - rust: nightly features: "--all-features" diff --git a/src/adaptors/auto_send.rs b/src/adaptors/auto_send.rs index 77ce8e25..3cacee42 100644 --- a/src/adaptors/auto_send.rs +++ b/src/adaptors/auto_send.rs @@ -28,13 +28,13 @@ use crate::{ /// ```rust /// use teloxide_core::{ /// requests::{Requester, RequesterExt}, -/// types::User, +/// types::Me, /// Bot, /// }; /// /// # async { /// let bot = Bot::new("TOKEN").auto_send(); -/// let myself: User = bot.get_me().await?; // No .send()! +/// let myself: Me = bot.get_me().await?; // No .send()! /// # Ok::<_, teloxide_core::RequestError>(()) }; /// ``` pub struct AutoSend {