1use layer_tl_types as tl;
35
36#[derive(Clone)]
40pub struct Button {
41 inner: tl::enums::KeyboardButton,
42}
43
44impl Button {
45 pub fn callback(text: impl Into<String>, data: impl Into<Vec<u8>>) -> Self {
47 Self {
48 inner: tl::enums::KeyboardButton::Callback(tl::types::KeyboardButtonCallback {
49 requires_password: false,
50 text: text.into(),
51 data: data.into(),
52 style: None,
53 }),
54 }
55 }
56
57 pub fn url(text: impl Into<String>, url: impl Into<String>) -> Self {
59 Self {
60 inner: tl::enums::KeyboardButton::Url(tl::types::KeyboardButtonUrl {
61 text: text.into(),
62 url: url.into(),
63 style: None,
64 }),
65 }
66 }
67
68 pub fn url_auth(
70 text: impl Into<String>,
71 url: impl Into<String>,
72 fwd_text: Option<String>,
73 bot: tl::enums::InputUser,
74 ) -> Self {
75 Self {
76 inner: tl::enums::KeyboardButton::InputKeyboardButtonUrlAuth(
77 tl::types::InputKeyboardButtonUrlAuth {
78 request_write_access: false,
79 text: text.into(),
80 fwd_text,
81 url: url.into(),
82 bot,
83 style: None,
84 },
85 ),
86 }
87 }
88
89 pub fn switch_inline(text: impl Into<String>, query: impl Into<String>) -> Self {
91 Self {
92 inner: tl::enums::KeyboardButton::SwitchInline(tl::types::KeyboardButtonSwitchInline {
93 same_peer: true,
94 peer_types: None,
95 text: text.into(),
96 query: query.into(),
97 style: None,
98 }),
99 }
100 }
101
102 pub fn text(label: impl Into<String>) -> Self {
104 Self {
105 inner: tl::enums::KeyboardButton::KeyboardButton(tl::types::KeyboardButton {
106 text: label.into(),
107 style: None,
108 }),
109 }
110 }
111
112 pub fn switch_elsewhere(text: impl Into<String>, query: impl Into<String>) -> Self {
114 Self {
115 inner: tl::enums::KeyboardButton::SwitchInline(tl::types::KeyboardButtonSwitchInline {
116 same_peer: false,
117 peer_types: None,
118 text: text.into(),
119 query: query.into(),
120 style: None,
121 }),
122 }
123 }
124
125 pub fn webview(text: impl Into<String>, url: impl Into<String>) -> Self {
127 Self {
128 inner: tl::enums::KeyboardButton::WebView(tl::types::KeyboardButtonWebView {
129 text: text.into(),
130 url: url.into(),
131 style: None,
132 }),
133 }
134 }
135
136 pub fn simple_webview(text: impl Into<String>, url: impl Into<String>) -> Self {
138 Self {
139 inner: tl::enums::KeyboardButton::SimpleWebView(
140 tl::types::KeyboardButtonSimpleWebView {
141 text: text.into(),
142 url: url.into(),
143 style: None,
144 },
145 ),
146 }
147 }
148
149 pub fn request_phone(text: impl Into<String>) -> Self {
151 Self {
152 inner: tl::enums::KeyboardButton::RequestPhone(tl::types::KeyboardButtonRequestPhone {
153 text: text.into(),
154 style: None,
155 }),
156 }
157 }
158
159 pub fn request_geo(text: impl Into<String>) -> Self {
161 Self {
162 inner: tl::enums::KeyboardButton::RequestGeoLocation(
163 tl::types::KeyboardButtonRequestGeoLocation {
164 text: text.into(),
165 style: None,
166 },
167 ),
168 }
169 }
170
171 pub fn request_poll(text: impl Into<String>) -> Self {
173 Self {
174 inner: tl::enums::KeyboardButton::RequestPoll(tl::types::KeyboardButtonRequestPoll {
175 quiz: None,
176 text: text.into(),
177 style: None,
178 }),
179 }
180 }
181
182 pub fn request_quiz(text: impl Into<String>) -> Self {
184 Self {
185 inner: tl::enums::KeyboardButton::RequestPoll(tl::types::KeyboardButtonRequestPoll {
186 quiz: Some(true),
187 text: text.into(),
188 style: None,
189 }),
190 }
191 }
192
193 pub fn game(text: impl Into<String>) -> Self {
195 Self {
196 inner: tl::enums::KeyboardButton::Game(tl::types::KeyboardButtonGame {
197 text: text.into(),
198 style: None,
199 }),
200 }
201 }
202
203 pub fn buy(text: impl Into<String>) -> Self {
205 Self {
206 inner: tl::enums::KeyboardButton::Buy(tl::types::KeyboardButtonBuy {
207 text: text.into(),
208 style: None,
209 }),
210 }
211 }
212
213 pub fn copy_text(text: impl Into<String>, copy_text: impl Into<String>) -> Self {
215 Self {
216 inner: tl::enums::KeyboardButton::Copy(tl::types::KeyboardButtonCopy {
217 text: text.into(),
218 copy_text: copy_text.into(),
219 style: None,
220 }),
221 }
222 }
223
224 pub fn into_raw(self) -> tl::enums::KeyboardButton {
226 self.inner
227 }
228}
229
230#[derive(Clone, Default)]
247pub struct InlineKeyboard {
248 rows: Vec<Vec<Button>>,
249}
250
251impl InlineKeyboard {
252 pub fn new() -> Self {
254 Self::default()
255 }
256
257 pub fn row(mut self, buttons: impl IntoIterator<Item = Button>) -> Self {
259 self.rows.push(buttons.into_iter().collect());
260 self
261 }
262
263 pub fn into_markup(self) -> tl::enums::ReplyMarkup {
265 let rows = self
266 .rows
267 .into_iter()
268 .map(|row| {
269 tl::enums::KeyboardButtonRow::KeyboardButtonRow(tl::types::KeyboardButtonRow {
270 buttons: row.into_iter().map(Button::into_raw).collect(),
271 })
272 })
273 .collect();
274
275 tl::enums::ReplyMarkup::ReplyInlineMarkup(tl::types::ReplyInlineMarkup { rows })
276 }
277}
278
279impl From<InlineKeyboard> for tl::enums::ReplyMarkup {
280 fn from(kb: InlineKeyboard) -> Self {
281 kb.into_markup()
282 }
283}
284
285#[derive(Clone, Default)]
289pub struct ReplyKeyboard {
290 rows: Vec<Vec<Button>>,
291 resize: bool,
292 single_use: bool,
293 selective: bool,
294}
295
296impl ReplyKeyboard {
297 pub fn new() -> Self {
299 Self::default()
300 }
301
302 pub fn row(mut self, buttons: impl IntoIterator<Item = Button>) -> Self {
304 self.rows.push(buttons.into_iter().collect());
305 self
306 }
307
308 pub fn resize(mut self) -> Self {
310 self.resize = true;
311 self
312 }
313
314 pub fn single_use(mut self) -> Self {
316 self.single_use = true;
317 self
318 }
319
320 pub fn selective(mut self) -> Self {
322 self.selective = true;
323 self
324 }
325
326 pub fn into_markup(self) -> tl::enums::ReplyMarkup {
328 let rows = self
329 .rows
330 .into_iter()
331 .map(|row| {
332 tl::enums::KeyboardButtonRow::KeyboardButtonRow(tl::types::KeyboardButtonRow {
333 buttons: row.into_iter().map(Button::into_raw).collect(),
334 })
335 })
336 .collect();
337
338 tl::enums::ReplyMarkup::ReplyKeyboardMarkup(tl::types::ReplyKeyboardMarkup {
339 resize: self.resize,
340 single_use: self.single_use,
341 selective: self.selective,
342 persistent: false,
343 rows,
344 placeholder: None,
345 })
346 }
347}
348
349impl From<ReplyKeyboard> for tl::enums::ReplyMarkup {
350 fn from(kb: ReplyKeyboard) -> Self {
351 kb.into_markup()
352 }
353}