1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
use serde::{Deserialize, Serialize};
#[derive(Default, Debug, Serialize, Deserialize, Clone)]
pub struct KeyboardButton {
/// Text of the button. If none of the optional fields are used, it will be sent as a message when the button is pressed
pub text: String,
// Optional fields omitted
}
impl<T: Into<String>> From<T> for KeyboardButton {
fn from(text: T) -> Self {
Self { text: text.into() }
}
}
#[derive(Default, Debug, Serialize, Deserialize, Clone)]
pub struct InlineKeyboardButton {
/// Label text on the button
pub text: String,
/// HTTP or tg:// url to be opened when button is pressed
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
/// Callback data to be sent in a callback query to the bot when button is pressed, 1-64 bytes.
#[serde(skip_serializing_if = "Option::is_none")]
pub callback_data: Option<String>,
}
impl<T: Into<String>> From<T> for InlineKeyboardButton {
fn from(text: T) -> Self {
Self {
text: text.into(),
..Default::default()
}
}
}
impl InlineKeyboardButton {
pub fn with_callback_data<T: Into<String>>(mut self, callback_data: T) -> Self {
self.callback_data = Some(callback_data.into());
self
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(untagged)]
pub enum ReplyMarkup {
InlineKeyboardMarkup {
/// Array of button rows, each represented by an Array of KeyboardButton objects
inline_keyboard: Vec<Vec<InlineKeyboardButton>>,
/// Requests clients to resize the keyboard vertically for optimal fit
resize_keyboard: bool,
/// Requests clients to hide the keyboard as soon as it's been used
one_time_keyboard: bool,
/// Use this parameter if you want to show the keyboard to specific users only
selective: bool,
/// The placeholder to be shown in the input field when the keyboard is active; 1-64 characters
#[serde(skip_serializing_if = "Option::is_none")]
input_field_placeholder: Option<String>,
/// Requests clients to always show the keyboard in the chat (users may not otherwise see the keyboard)
is_persistent: bool,
},
ReplyKeyboardMarkup {
/// Array of button rows, each represented by an Array of KeyboardButton objects
keyboard: Vec<Vec<KeyboardButton>>,
/// Requests clients to resize the keyboard vertically for optimal fit
resize_keyboard: bool,
/// Requests clients to hide the keyboard as soon as it's been used
one_time_keyboard: bool,
/// Use this parameter if you want to show the keyboard to specific users only
selective: bool,
/// The placeholder to be shown in the input field when the keyboard is active; 1-64 characters
#[serde(skip_serializing_if = "Option::is_none")]
input_field_placeholder: Option<String>,
/// Requests clients to always show the keyboard in the chat (users may not otherwise see the keyboard)
is_persistent: bool,
},
ReplyKeyboardRemove {
/// 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)
remove_keyboard: bool,
/// Use this parameter if you want to remove the keyboard for specific users only
selective: bool,
},
ForceReply {
/// Shows reply interface to the user, as if they manually selected the bot's message and tapped 'Reply'
force_reply: bool,
/// The placeholder to be shown in the input field when the keyboard is active; 1-64 characters
#[serde(skip_serializing_if = "Option::is_none")]
input_field_placeholder: Option<String>,
/// Use this parameter if you want to force reply from specific users only
selective: bool,
},
}
impl ReplyMarkup {
pub fn inline_keyboard_markup(inline_keyboard: Vec<Vec<InlineKeyboardButton>>) -> ReplyMarkup {
ReplyMarkup::InlineKeyboardMarkup {
inline_keyboard,
resize_keyboard: false,
one_time_keyboard: false,
selective: false,
input_field_placeholder: None,
is_persistent: false,
}
}
pub fn reply_keyboard_markup(keyboard: Vec<Vec<KeyboardButton>>) -> ReplyMarkup {
ReplyMarkup::ReplyKeyboardMarkup {
keyboard,
resize_keyboard: false,
one_time_keyboard: true,
selective: false,
input_field_placeholder: None,
is_persistent: false,
}
}
pub fn reply_keyboard_remove() -> ReplyMarkup {
ReplyMarkup::ReplyKeyboardRemove {
remove_keyboard: true,
selective: false,
}
}
pub fn force_reply() -> ReplyMarkup {
ReplyMarkup::ForceReply {
force_reply: true,
input_field_placeholder: None,
selective: false,
}
}
}
impl<T: Into<String>> From<T> for ReplyMarkup {
fn from(text: T) -> Self {
serde_json::from_str(&text.into()).unwrap()
}
}