diff --git a/CHANGELOG.md b/CHANGELOG.md index 12fcb260..664a9483 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Refactor `ReplyMarkup` ([#pr65][pr65]) (**BC**) + - Rename `ReplyMarkup::{InlineKeyboardMarkup => InlineKeyboard, ReplyKeyboardMarkup => Keyboard, ReplyKeyboardRemove => KeyboardRemove}` + - Add `inline_kb`, `keyboad`, `kb_remove` and `force_reply` `ReplyMarkup` consructors + - Rename `ReplyKeyboardMarkup` => `KeyboardMarkup` + - Rename `ReplyKeyboardRemove` => `KeyboardRemove` + - Remove useless generic param from `ReplyKeyboardMarkup::new` and `InlineKeyboardMarkup::new` + - Change parameters order in `ReplyKeyboardMarkup::append_to_row` and `InlineKeyboardMarkup::append_to_row` - Support telegram bot API version 5.1 (see it's [changelog](https://core.telegram.org/bots/api#march-9-2021)) ([#pr63][pr63]) (**BC**) - Support telegram bot API version 5.0 (see it's [changelog](https://core.telegram.org/bots/api#november-4-2020)) ([#pr62][pr62]) (**BC**) @@ -24,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Make `MediaContact::contact` public ([#pr64][pr64]) - `set_webhook` signature (make `allowed_updates` optional) ([#59][pr59]) - Fix typos in payloads ([#57][pr57]): - `get_updates`: `offset` `i64` -> `i32` @@ -33,6 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [pr56]: https://github.com/teloxide/teloxide-core/pull/56 [pr57]: https://github.com/teloxide/teloxide-core/pull/57 [pr59]: https://github.com/teloxide/teloxide-core/pull/59 +[pr64]: https://github.com/teloxide/teloxide-core/pull/64 ### Changed diff --git a/src/types/inline_keyboard_markup.rs b/src/types/inline_keyboard_markup.rs index 76294ddd..10828a80 100644 --- a/src/types/inline_keyboard_markup.rs +++ b/src/types/inline_keyboard_markup.rs @@ -30,10 +30,10 @@ pub struct InlineKeyboardMarkup { /// let keyboard = InlineKeyboardMarkup::default().append_row(vec![url_button]); /// ``` impl InlineKeyboardMarkup { - pub fn new(inline_keyboard: I1) -> Self + pub fn new(inline_keyboard: I) -> Self where - I1: IntoIterator, - I2: IntoIterator, + I: IntoIterator, + I::Item: IntoIterator, { Self { inline_keyboard: inline_keyboard @@ -44,10 +44,10 @@ impl InlineKeyboardMarkup { } } - pub fn inline_keyboard(mut self, val: I1) -> Self + pub fn inline_keyboard(mut self, val: I) -> Self where - I1: IntoIterator, - I2: IntoIterator, + I: IntoIterator, + I::Item: IntoIterator, { self.inline_keyboard = val .into_iter() @@ -65,7 +65,7 @@ impl InlineKeyboardMarkup { self } - pub fn append_to_row(mut self, button: InlineKeyboardButton, index: usize) -> Self { + pub fn append_to_row(mut self, index: usize, button: InlineKeyboardButton) -> Self { match self.inline_keyboard.get_mut(index) { Some(buttons) => buttons.push(button), None => self.inline_keyboard.push(vec![button]), @@ -100,7 +100,7 @@ mod tests { let markup = InlineKeyboardMarkup::default() .append_row(vec![button1.clone()]) - .append_to_row(button2.clone(), 0); + .append_to_row(0, button2.clone()); let expected = InlineKeyboardMarkup { inline_keyboard: vec![vec![button1, button2]], @@ -116,7 +116,7 @@ mod tests { let markup = InlineKeyboardMarkup::default() .append_row(vec![button1.clone()]) - .append_to_row(button2.clone(), 1); + .append_to_row(1, button2.clone()); let expected = InlineKeyboardMarkup { inline_keyboard: vec![vec![button1], vec![button2]], diff --git a/src/types/reply_keyboard_markup.rs b/src/types/reply_keyboard_markup.rs index b2e8d3b1..0b99d1d5 100644 --- a/src/types/reply_keyboard_markup.rs +++ b/src/types/reply_keyboard_markup.rs @@ -11,7 +11,7 @@ use crate::types::KeyboardButton; /// [Introduction to bots]: https://core.telegram.org/bots#keyboards #[serde_with_macros::skip_serializing_none] #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, Default)] -pub struct ReplyKeyboardMarkup { +pub struct KeyboardMarkup { /// Array of button rows, each represented by an Array of /// [`KeyboardButton`] objects /// @@ -44,11 +44,11 @@ pub struct ReplyKeyboardMarkup { pub selective: Option, } -impl ReplyKeyboardMarkup { - pub fn new(keyboard: K1) -> Self +impl KeyboardMarkup { + pub fn new(keyboard: K) -> Self where - K1: IntoIterator, - K2: IntoIterator, + K: IntoIterator, + K::Item: IntoIterator, { Self { keyboard: keyboard @@ -67,7 +67,7 @@ impl ReplyKeyboardMarkup { self } - pub fn append_to_row(mut self, button: KeyboardButton, index: usize) -> Self { + pub fn append_to_row(mut self, index: usize, button: KeyboardButton) -> Self { match self.keyboard.get_mut(index) { Some(buttons) => buttons.push(button), None => self.keyboard.push(vec![button]), diff --git a/src/types/reply_keyboard_remove.rs b/src/types/reply_keyboard_remove.rs index 2e9c81f6..5acb6ccc 100644 --- a/src/types/reply_keyboard_remove.rs +++ b/src/types/reply_keyboard_remove.rs @@ -7,20 +7,20 @@ use crate::types::True; /// /// By default, custom keyboards are displayed until a new keyboard is sent by a /// bot. An exception is made for one-time keyboards that are hidden immediately -/// after the user presses a button (see [`ReplyKeyboardMarkup`]). +/// after the user presses a button (see [`KeyboardMarkup`]). /// /// [The official docs](https://core.telegram.org/bots/api#replykeyboardremove). /// -/// [`ReplyKeyboardMarkup`]: crate::types::ReplyKeyboardMarkup +/// [`KeyboardMarkup`]: crate::types::KeyboardMarkup #[serde_with_macros::skip_serializing_none] #[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq, Serialize, Deserialize)] -pub struct ReplyKeyboardRemove { +pub struct KeyboardRemove { /// Requests clients to remove the custom keyboard (user will not be able /// to summon this keyboard; if you want to hide the keyboard from sight /// but keep it accessible, use one_time_keyboard in - /// [`ReplyKeyboardMarkup`]). + /// [`KeyboardMarkup`]). /// - /// [`ReplyKeyboardMarkup`]: crate::types::ReplyKeyboardMarkup + /// [`KeyboardMarkup`]: crate::types::KeyboardMarkup pub remove_keyboard: True, /// Use this parameter if you want to remove the keyboard for specific @@ -36,7 +36,7 @@ pub struct ReplyKeyboardRemove { pub selective: Option, } -impl ReplyKeyboardRemove { +impl KeyboardRemove { pub const fn new() -> Self { Self { remove_keyboard: True, diff --git a/src/types/reply_markup.rs b/src/types/reply_markup.rs index 5f0afbbe..233f2584 100644 --- a/src/types/reply_markup.rs +++ b/src/types/reply_markup.rs @@ -1,17 +1,69 @@ use derive_more::From; use serde::{Deserialize, Serialize}; -use crate::types::{ForceReply, InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove}; +use crate::types::{ + ForceReply, InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, KeyboardMarkup, + KeyboardRemove, +}; #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, From)] #[serde(untagged)] pub enum ReplyMarkup { - InlineKeyboardMarkup(InlineKeyboardMarkup), - ReplyKeyboardMarkup(ReplyKeyboardMarkup), - ReplyKeyboardRemove(ReplyKeyboardRemove), + InlineKeyboard(InlineKeyboardMarkup), + Keyboard(KeyboardMarkup), + KeyboardRemove(KeyboardRemove), ForceReply(ForceReply), } +impl ReplyMarkup { + /// Constructor for [`InlineKeyboard`] variant. + /// + /// This is a shortcut to + /// `ReplyMarkup::InlineKeyboard(InlineKeyboardMarkup::new(_))`. + /// + /// [`InlineKeyboard`]: ReplyMarkup::InlineKeyboard + pub fn inline_kb(inline_keyboard: I) -> Self + where + I: IntoIterator, + I::Item: IntoIterator, + { + Self::InlineKeyboard(InlineKeyboardMarkup::new(inline_keyboard)) + } + + /// Constructor for [`Keyboard`] variant. + /// + /// This is a shortcut to + /// `ReplyMarkup::Keyboard(KeyboardMarkup::new(_))`. + /// + /// [`Keyboard`]: ReplyMarkup::Keyboard + pub fn keyboad(keyboard: K) -> Self + where + K: IntoIterator, + K::Item: IntoIterator, + { + Self::Keyboard(KeyboardMarkup::new(keyboard)) + } + + /// Constructor for [`KeyboardRemove`] variant. + /// + /// This is a shortcut to + /// `ReplyMarkup::KeyboardRemove(ReplyKeyboardRemove::new()))`. + /// + /// [`KeyboardRemove`]: ReplyMarkup::KeyboardRemove + pub fn kb_remove() -> Self { + Self::KeyboardRemove(KeyboardRemove::new()) + } + + /// Constructor for [`ForceReply`] variant. + /// + /// This is a shortcut to `ReplyMarkup::ForceReply(ForceReply::new())`. + /// + /// [`ForceReply`]: ReplyMarkup::KeyboardRemove + pub fn force_reply() -> Self { + Self::ForceReply(ForceReply::new()) + } +} + #[cfg(test)] mod tests { use super::*; @@ -19,7 +71,7 @@ mod tests { #[test] fn inline_keyboard_markup() { let data = InlineKeyboardMarkup::default(); - let expected = ReplyMarkup::InlineKeyboardMarkup(data.clone()); + let expected = ReplyMarkup::InlineKeyboard(data.clone()); let actual: ReplyMarkup = data.into(); assert_eq!(actual, expected) }