mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-23 06:51:01 +01:00
Simplify building ReplyKeyboardMarkup
This commit is contained in:
parent
f436a0269b
commit
2c4102e2b3
4 changed files with 81 additions and 47 deletions
|
@ -21,29 +21,12 @@ enum FavouriteMusic {
|
||||||
|
|
||||||
impl FavouriteMusic {
|
impl FavouriteMusic {
|
||||||
fn markup() -> ReplyKeyboardMarkup {
|
fn markup() -> ReplyKeyboardMarkup {
|
||||||
ReplyKeyboardMarkup {
|
ReplyKeyboardMarkup::default().append_row(vec![
|
||||||
keyboard: vec![vec![
|
KeyboardButton::new("Rock"),
|
||||||
KeyboardButton {
|
KeyboardButton::new("Metal"),
|
||||||
text: "Rock".to_owned(),
|
KeyboardButton::new("Pop"),
|
||||||
request: None,
|
KeyboardButton::new("Other"),
|
||||||
},
|
])
|
||||||
KeyboardButton {
|
|
||||||
text: "Metal".to_owned(),
|
|
||||||
request: None,
|
|
||||||
},
|
|
||||||
KeyboardButton {
|
|
||||||
text: "Pop".to_owned(),
|
|
||||||
request: None,
|
|
||||||
},
|
|
||||||
KeyboardButton {
|
|
||||||
text: "Other".to_owned(),
|
|
||||||
request: None,
|
|
||||||
},
|
|
||||||
]],
|
|
||||||
resize_keyboard: None,
|
|
||||||
one_time_keyboard: None,
|
|
||||||
selective: None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,21 +53,13 @@ impl Display for User {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// [Some macros]
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! reply {
|
|
||||||
($ctx:ident, $text:expr) => {
|
|
||||||
$ctx.reply($text).await?;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [Control our FSM]
|
// [Control our FSM]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
|
type Ctx = SessionHandlerCtx<Message, User>;
|
||||||
|
type Res = Result<SessionState<User>, RequestError>;
|
||||||
|
|
||||||
async fn send_favourite_music_types(ctx: &Ctx) -> Result<(), RequestError> {
|
async fn send_favourite_music_types(ctx: &Ctx) -> Result<(), RequestError> {
|
||||||
ctx.bot
|
ctx.bot
|
||||||
.send_message(ctx.chat_id(), "Good. Now choose your favourite music:")
|
.send_message(ctx.chat_id(), "Good. Now choose your favourite music:")
|
||||||
|
@ -94,16 +69,14 @@ async fn send_favourite_music_types(ctx: &Ctx) -> Result<(), RequestError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
type Ctx = SessionHandlerCtx<Message, User>;
|
|
||||||
type Res = Result<SessionState<User>, RequestError>;
|
|
||||||
|
|
||||||
async fn start(ctx: Ctx) -> Res {
|
async fn start(ctx: Ctx) -> Res {
|
||||||
reply!(ctx, "Let's start! First, what's your full name?");
|
ctx.reply("Let's start! First, what's your full name?")
|
||||||
|
.await?;
|
||||||
Ok(SessionState::Next(ctx.session))
|
Ok(SessionState::Next(ctx.session))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn full_name(mut ctx: Ctx) -> Res {
|
async fn full_name(mut ctx: Ctx) -> Res {
|
||||||
reply!(ctx, "What a wonderful name! Your age?");
|
ctx.reply("What a wonderful name! Your age?").await?;
|
||||||
ctx.session.full_name = Some(ctx.update.text().unwrap().to_owned());
|
ctx.session.full_name = Some(ctx.update.text().unwrap().to_owned());
|
||||||
Ok(SessionState::Next(ctx.session))
|
Ok(SessionState::Next(ctx.session))
|
||||||
}
|
}
|
||||||
|
@ -114,7 +87,7 @@ async fn age(mut ctx: Ctx) -> Res {
|
||||||
send_favourite_music_types(&ctx).await?;
|
send_favourite_music_types(&ctx).await?;
|
||||||
ctx.session.age = Some(ok);
|
ctx.session.age = Some(ok);
|
||||||
}
|
}
|
||||||
Err(_) => reply!(ctx, "Oh, please, enter a number!"),
|
Err(_) => ctx.reply("Oh, please, enter a number!").await?,
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(SessionState::Next(ctx.session))
|
Ok(SessionState::Next(ctx.session))
|
||||||
|
@ -124,11 +97,11 @@ async fn favourite_music(mut ctx: Ctx) -> Res {
|
||||||
match ctx.update.text().unwrap().parse() {
|
match ctx.update.text().unwrap().parse() {
|
||||||
Ok(ok) => {
|
Ok(ok) => {
|
||||||
ctx.session.favourite_music = Some(ok);
|
ctx.session.favourite_music = Some(ok);
|
||||||
reply!(ctx, format!("Fine. {}", ctx.session));
|
ctx.reply(format!("Fine. {}", ctx.session)).await?;
|
||||||
Ok(SessionState::Exit)
|
Ok(SessionState::Exit)
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
reply!(ctx, "Oh, please, enter from the keyboard!");
|
ctx.reply("Oh, please, enter from the keyboard!").await?;
|
||||||
Ok(SessionState::Next(ctx.session))
|
Ok(SessionState::Next(ctx.session))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,10 +33,6 @@ pub struct InlineKeyboardMarkup {
|
||||||
/// let keyboard = InlineKeyboardMarkup::new().append_row(vec![url_button]);
|
/// let keyboard = InlineKeyboardMarkup::new().append_row(vec![url_button]);
|
||||||
/// ```
|
/// ```
|
||||||
impl InlineKeyboardMarkup {
|
impl InlineKeyboardMarkup {
|
||||||
pub fn new() -> Self {
|
|
||||||
<_>::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn append_row(mut self, buttons: Vec<InlineKeyboardButton>) -> Self {
|
pub fn append_row(mut self, buttons: Vec<InlineKeyboardButton>) -> Self {
|
||||||
self.inline_keyboard.push(buttons);
|
self.inline_keyboard.push(buttons);
|
||||||
self
|
self
|
||||||
|
|
|
@ -24,6 +24,28 @@ pub struct KeyboardButton {
|
||||||
pub request: Option<ButtonRequest>,
|
pub request: Option<ButtonRequest>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl KeyboardButton {
|
||||||
|
/// Creates `KeyboardButton` with the provided `text` and all the other
|
||||||
|
/// fields set to `None`.
|
||||||
|
pub fn new<T>(text: T) -> Self
|
||||||
|
where
|
||||||
|
T: Into<String>,
|
||||||
|
{
|
||||||
|
Self {
|
||||||
|
text: text.into(),
|
||||||
|
request: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn request<T>(mut self, val: T) -> Self
|
||||||
|
where
|
||||||
|
T: Into<Option<ButtonRequest>>,
|
||||||
|
{
|
||||||
|
self.request = val.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Serialize + Deserialize are implemented by hand
|
// Serialize + Deserialize are implemented by hand
|
||||||
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
|
||||||
pub enum ButtonRequest {
|
pub enum ButtonRequest {
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::types::KeyboardButton;
|
||||||
/// [custom keyboard]: https://core.telegram.org/bots#keyboards
|
/// [custom keyboard]: https://core.telegram.org/bots#keyboards
|
||||||
/// [Introduction to bots]: https://core.telegram.org/bots#keyboards
|
/// [Introduction to bots]: https://core.telegram.org/bots#keyboards
|
||||||
#[serde_with_macros::skip_serializing_none]
|
#[serde_with_macros::skip_serializing_none]
|
||||||
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, Default)]
|
||||||
pub struct ReplyKeyboardMarkup {
|
pub struct ReplyKeyboardMarkup {
|
||||||
/// Array of button rows, each represented by an Array of
|
/// Array of button rows, each represented by an Array of
|
||||||
/// [`KeyboardButton`] objects
|
/// [`KeyboardButton`] objects
|
||||||
|
@ -43,3 +43,46 @@ pub struct ReplyKeyboardMarkup {
|
||||||
/// [`Message`]: crate::types::Message
|
/// [`Message`]: crate::types::Message
|
||||||
pub selective: Option<bool>,
|
pub selective: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ReplyKeyboardMarkup {
|
||||||
|
pub fn append_row(mut self, buttons: Vec<KeyboardButton>) -> Self {
|
||||||
|
self.keyboard.push(buttons);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn append_to_row(
|
||||||
|
mut self,
|
||||||
|
button: KeyboardButton,
|
||||||
|
index: usize,
|
||||||
|
) -> Self {
|
||||||
|
match self.keyboard.get_mut(index) {
|
||||||
|
Some(buttons) => buttons.push(button),
|
||||||
|
None => self.keyboard.push(vec![button]),
|
||||||
|
};
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resize_keyboard<T>(mut self, val: T) -> Self
|
||||||
|
where
|
||||||
|
T: Into<Option<bool>>,
|
||||||
|
{
|
||||||
|
self.resize_keyboard = val.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn one_time_keyboard<T>(mut self, val: T) -> Self
|
||||||
|
where
|
||||||
|
T: Into<Option<bool>>,
|
||||||
|
{
|
||||||
|
self.one_time_keyboard = val.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn selective<T>(mut self, val: T) -> Self
|
||||||
|
where
|
||||||
|
T: Into<Option<bool>>,
|
||||||
|
{
|
||||||
|
self.selective = val.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue