1use std::future::{Future, IntoFuture};
2use std::pin::Pin;
3
4use serde::Serialize;
5
6use rustigram_types::checklist::InputChecklist;
7use rustigram_types::keyboard::InlineKeyboardMarkup;
8use rustigram_types::message::{LinkPreviewOptions, Message, MessageEntity, ParseMode};
9use rustigram_types::user::ChatId;
10
11use crate::client::BotClient;
12use crate::error::Result;
13
14macro_rules! impl_into_future {
18 ($builder:ident, $return_ty:ty, $method:literal) => {
19 impl IntoFuture for $builder {
20 type Output = Result<$return_ty>;
21 type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
22
23 fn into_future(self) -> Self::IntoFuture {
24 Box::pin(async move { self.client.post_json($method, &self.params).await })
25 }
26 }
27 };
28}
29
30#[derive(Serialize)]
32#[serde(untagged)]
33pub enum EditTarget {
35 Chat {
37 chat_id: ChatId,
39 message_id: i64,
41 },
42 Inline {
44 inline_message_id: String,
46 },
47}
48
49#[derive(Serialize)]
52struct EditMessageTextParams {
53 #[serde(flatten)]
54 target: EditTarget,
55 text: String,
56 #[serde(skip_serializing_if = "Option::is_none")]
57 business_connection_id: Option<String>,
58 #[serde(skip_serializing_if = "Option::is_none")]
59 parse_mode: Option<ParseMode>,
60 #[serde(skip_serializing_if = "Option::is_none")]
61 entities: Option<Vec<MessageEntity>>,
62 #[serde(skip_serializing_if = "Option::is_none")]
63 link_preview_options: Option<LinkPreviewOptions>,
64 #[serde(skip_serializing_if = "Option::is_none")]
65 reply_markup: Option<InlineKeyboardMarkup>,
66}
67
68pub struct EditMessageText {
70 client: BotClient,
71 params: EditMessageTextParams,
72}
73
74impl EditMessageText {
75 pub(crate) fn in_chat(
76 client: BotClient,
77 chat_id: impl Into<ChatId>,
78 message_id: i64,
79 text: impl Into<String>,
80 ) -> Self {
81 Self {
82 client,
83 params: EditMessageTextParams {
84 target: EditTarget::Chat {
85 chat_id: chat_id.into(),
86 message_id,
87 },
88 text: text.into(),
89 business_connection_id: None,
90 parse_mode: None,
91 entities: None,
92 link_preview_options: None,
93 reply_markup: None,
94 },
95 }
96 }
97 pub(crate) fn inline(
98 client: BotClient,
99 inline_message_id: impl Into<String>,
100 text: impl Into<String>,
101 ) -> Self {
102 Self {
103 client,
104 params: EditMessageTextParams {
105 target: EditTarget::Inline {
106 inline_message_id: inline_message_id.into(),
107 },
108 text: text.into(),
109 business_connection_id: None,
110 parse_mode: None,
111 entities: None,
112 link_preview_options: None,
113 reply_markup: None,
114 },
115 }
116 }
117 pub fn parse_mode(mut self, m: ParseMode) -> Self {
119 self.params.parse_mode = Some(m);
120 self
121 }
122 pub fn entities(mut self, e: Vec<MessageEntity>) -> Self {
124 self.params.entities = Some(e);
125 self
126 }
127 pub fn link_preview_options(mut self, o: LinkPreviewOptions) -> Self {
129 self.params.link_preview_options = Some(o);
130 self
131 }
132 pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
134 self.params.reply_markup = Some(m);
135 self
136 }
137}
138
139impl_into_future!(EditMessageText, Message, "editMessageText");
140
141#[derive(Serialize)]
144struct EditMessageCaptionParams {
145 #[serde(flatten)]
146 target: EditTarget,
147 #[serde(skip_serializing_if = "Option::is_none")]
148 business_connection_id: Option<String>,
149 #[serde(skip_serializing_if = "Option::is_none")]
150 caption: Option<String>,
151 #[serde(skip_serializing_if = "Option::is_none")]
152 parse_mode: Option<ParseMode>,
153 #[serde(skip_serializing_if = "Option::is_none")]
154 caption_entities: Option<Vec<MessageEntity>>,
155 #[serde(skip_serializing_if = "Option::is_none")]
156 show_caption_above_media: Option<bool>,
157 #[serde(skip_serializing_if = "Option::is_none")]
158 reply_markup: Option<InlineKeyboardMarkup>,
159}
160
161pub struct EditMessageCaption {
163 client: BotClient,
164 params: EditMessageCaptionParams,
165}
166
167impl EditMessageCaption {
168 pub(crate) fn in_chat(client: BotClient, chat_id: impl Into<ChatId>, message_id: i64) -> Self {
169 Self {
170 client,
171 params: EditMessageCaptionParams {
172 target: EditTarget::Chat {
173 chat_id: chat_id.into(),
174 message_id,
175 },
176 business_connection_id: None,
177 caption: None,
178 parse_mode: None,
179 caption_entities: None,
180 show_caption_above_media: None,
181 reply_markup: None,
182 },
183 }
184 }
185 pub(crate) fn inline(client: BotClient, inline_message_id: impl Into<String>) -> Self {
186 Self {
187 client,
188 params: EditMessageCaptionParams {
189 target: EditTarget::Inline {
190 inline_message_id: inline_message_id.into(),
191 },
192 business_connection_id: None,
193 caption: None,
194 parse_mode: None,
195 caption_entities: None,
196 show_caption_above_media: None,
197 reply_markup: None,
198 },
199 }
200 }
201 pub fn caption(mut self, c: impl Into<String>) -> Self {
203 self.params.caption = Some(c.into());
204 self
205 }
206 pub fn parse_mode(mut self, m: ParseMode) -> Self {
208 self.params.parse_mode = Some(m);
209 self
210 }
211 pub fn show_caption_above_media(mut self, v: bool) -> Self {
213 self.params.show_caption_above_media = Some(v);
214 self
215 }
216 pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
218 self.params.reply_markup = Some(m);
219 self
220 }
221}
222
223impl_into_future!(EditMessageCaption, Message, "editMessageCaption");
224
225#[derive(Serialize)]
228struct EditMessageMediaParams {
229 #[serde(flatten)]
230 target: EditTarget,
231 media: serde_json::Value,
236 #[serde(skip_serializing_if = "Option::is_none")]
237 business_connection_id: Option<String>,
238 #[serde(skip_serializing_if = "Option::is_none")]
239 reply_markup: Option<InlineKeyboardMarkup>,
240}
241
242pub struct EditMessageMedia {
250 client: BotClient,
251 params: EditMessageMediaParams,
252}
253
254impl EditMessageMedia {
255 pub(crate) fn in_chat(
256 client: BotClient,
257 chat_id: impl Into<ChatId>,
258 message_id: i64,
259 media: serde_json::Value,
260 ) -> Self {
261 Self {
262 client,
263 params: EditMessageMediaParams {
264 target: EditTarget::Chat {
265 chat_id: chat_id.into(),
266 message_id,
267 },
268 media,
269 business_connection_id: None,
270 reply_markup: None,
271 },
272 }
273 }
274 pub(crate) fn inline(
275 client: BotClient,
276 inline_message_id: impl Into<String>,
277 media: serde_json::Value,
278 ) -> Self {
279 Self {
280 client,
281 params: EditMessageMediaParams {
282 target: EditTarget::Inline {
283 inline_message_id: inline_message_id.into(),
284 },
285 media,
286 business_connection_id: None,
287 reply_markup: None,
288 },
289 }
290 }
291 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
293 self.params.business_connection_id = Some(id.into());
294 self
295 }
296 pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
298 self.params.reply_markup = Some(m);
299 self
300 }
301}
302
303impl_into_future!(EditMessageMedia, Message, "editMessageMedia");
304
305#[derive(Serialize)]
308struct EditMessageReplyMarkupParams {
309 #[serde(flatten)]
310 target: EditTarget,
311 #[serde(skip_serializing_if = "Option::is_none")]
312 business_connection_id: Option<String>,
313 #[serde(skip_serializing_if = "Option::is_none")]
314 reply_markup: Option<InlineKeyboardMarkup>,
315}
316
317pub struct EditMessageReplyMarkup {
319 client: BotClient,
320 params: EditMessageReplyMarkupParams,
321}
322
323impl EditMessageReplyMarkup {
324 pub(crate) fn in_chat(client: BotClient, chat_id: impl Into<ChatId>, message_id: i64) -> Self {
325 Self {
326 client,
327 params: EditMessageReplyMarkupParams {
328 target: EditTarget::Chat {
329 chat_id: chat_id.into(),
330 message_id,
331 },
332 business_connection_id: None,
333 reply_markup: None,
334 },
335 }
336 }
337 pub(crate) fn inline(client: BotClient, inline_message_id: impl Into<String>) -> Self {
338 Self {
339 client,
340 params: EditMessageReplyMarkupParams {
341 target: EditTarget::Inline {
342 inline_message_id: inline_message_id.into(),
343 },
344 business_connection_id: None,
345 reply_markup: None,
346 },
347 }
348 }
349 pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
351 self.params.reply_markup = Some(m);
352 self
353 }
354 pub fn remove_markup(mut self) -> Self {
356 self.params.reply_markup = None;
357 self
358 }
359}
360
361impl_into_future!(EditMessageReplyMarkup, Message, "editMessageReplyMarkup");
362
363#[derive(Serialize)]
366struct EditMessageChecklistParams {
367 business_connection_id: String,
368 chat_id: i64,
369 message_id: i64,
370 checklist: InputChecklist,
371 #[serde(skip_serializing_if = "Option::is_none")]
372 reply_markup: Option<InlineKeyboardMarkup>,
373}
374
375pub struct EditMessageChecklist {
380 client: BotClient,
381 params: EditMessageChecklistParams,
382}
383
384impl EditMessageChecklist {
385 pub(crate) fn new(
386 client: BotClient,
387 business_connection_id: impl Into<String>,
388 chat_id: i64,
389 message_id: i64,
390 checklist: InputChecklist,
391 ) -> Self {
392 Self {
393 client,
394 params: EditMessageChecklistParams {
395 business_connection_id: business_connection_id.into(),
396 chat_id,
397 message_id,
398 checklist,
399 reply_markup: None,
400 },
401 }
402 }
403 pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
405 self.params.reply_markup = Some(m);
406 self
407 }
408}
409
410impl_into_future!(EditMessageChecklist, Message, "editMessageChecklist");
411
412#[derive(Serialize)]
415struct ApproveSuggestedPostParams {
416 chat_id: i64,
417 message_id: i64,
418 #[serde(skip_serializing_if = "Option::is_none")]
419 send_date: Option<i64>,
420}
421
422pub struct ApproveSuggestedPost {
427 client: BotClient,
428 params: ApproveSuggestedPostParams,
429}
430
431impl ApproveSuggestedPost {
432 pub(crate) fn new(client: BotClient, chat_id: i64, message_id: i64) -> Self {
433 Self {
434 client,
435 params: ApproveSuggestedPostParams {
436 chat_id,
437 message_id,
438 send_date: None,
439 },
440 }
441 }
442 pub fn send_date(mut self, ts: i64) -> Self {
446 self.params.send_date = Some(ts);
447 self
448 }
449}
450
451impl_into_future!(ApproveSuggestedPost, bool, "approveSuggestedPost");
452
453#[derive(Serialize)]
456struct DeclineSuggestedPostParams {
457 chat_id: i64,
458 message_id: i64,
459 #[serde(skip_serializing_if = "Option::is_none")]
460 comment: Option<String>,
461}
462
463pub struct DeclineSuggestedPost {
468 client: BotClient,
469 params: DeclineSuggestedPostParams,
470}
471
472impl DeclineSuggestedPost {
473 pub(crate) fn new(client: BotClient, chat_id: i64, message_id: i64) -> Self {
474 Self {
475 client,
476 params: DeclineSuggestedPostParams {
477 chat_id,
478 message_id,
479 comment: None,
480 },
481 }
482 }
483 pub fn comment(mut self, c: impl Into<String>) -> Self {
485 self.params.comment = Some(c.into());
486 self
487 }
488}
489
490impl_into_future!(DeclineSuggestedPost, bool, "declineSuggestedPost");
491
492#[derive(Serialize)]
495struct EditMessageLiveLocationParams {
496 #[serde(flatten)]
497 target: EditTarget,
498 latitude: f64,
499 longitude: f64,
500 #[serde(skip_serializing_if = "Option::is_none")]
501 live_period: Option<u32>,
502 #[serde(skip_serializing_if = "Option::is_none")]
503 horizontal_accuracy: Option<f64>,
504 #[serde(skip_serializing_if = "Option::is_none")]
505 heading: Option<u16>,
506 #[serde(skip_serializing_if = "Option::is_none")]
507 proximity_alert_radius: Option<u32>,
508 #[serde(skip_serializing_if = "Option::is_none")]
509 reply_markup: Option<InlineKeyboardMarkup>,
510}
511
512pub struct EditMessageLiveLocation {
514 client: BotClient,
515 params: EditMessageLiveLocationParams,
516}
517
518impl EditMessageLiveLocation {
519 pub(crate) fn in_chat(
520 client: BotClient,
521 chat_id: impl Into<ChatId>,
522 message_id: i64,
523 latitude: f64,
524 longitude: f64,
525 ) -> Self {
526 Self {
527 client,
528 params: EditMessageLiveLocationParams {
529 target: EditTarget::Chat {
530 chat_id: chat_id.into(),
531 message_id,
532 },
533 latitude,
534 longitude,
535 live_period: None,
536 horizontal_accuracy: None,
537 heading: None,
538 proximity_alert_radius: None,
539 reply_markup: None,
540 },
541 }
542 }
543 pub(crate) fn inline(
544 client: BotClient,
545 inline_message_id: impl Into<String>,
546 latitude: f64,
547 longitude: f64,
548 ) -> Self {
549 Self {
550 client,
551 params: EditMessageLiveLocationParams {
552 target: EditTarget::Inline {
553 inline_message_id: inline_message_id.into(),
554 },
555 latitude,
556 longitude,
557 live_period: None,
558 horizontal_accuracy: None,
559 heading: None,
560 proximity_alert_radius: None,
561 reply_markup: None,
562 },
563 }
564 }
565 pub fn live_period(mut self, v: u32) -> Self {
567 self.params.live_period = Some(v);
568 self
569 }
570 pub fn heading(mut self, v: u16) -> Self {
572 self.params.heading = Some(v);
573 self
574 }
575 pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
577 self.params.reply_markup = Some(m);
578 self
579 }
580}
581
582impl_into_future!(EditMessageLiveLocation, Message, "editMessageLiveLocation");
583
584#[derive(Serialize)]
587struct StopMessageLiveLocationParams {
588 #[serde(flatten)]
589 target: EditTarget,
590 #[serde(skip_serializing_if = "Option::is_none")]
591 reply_markup: Option<InlineKeyboardMarkup>,
592}
593
594pub struct StopMessageLiveLocation {
596 client: BotClient,
597 params: StopMessageLiveLocationParams,
598}
599
600impl StopMessageLiveLocation {
601 pub(crate) fn in_chat(client: BotClient, chat_id: impl Into<ChatId>, message_id: i64) -> Self {
602 Self {
603 client,
604 params: StopMessageLiveLocationParams {
605 target: EditTarget::Chat {
606 chat_id: chat_id.into(),
607 message_id,
608 },
609 reply_markup: None,
610 },
611 }
612 }
613 pub(crate) fn inline(client: BotClient, inline_message_id: impl Into<String>) -> Self {
614 Self {
615 client,
616 params: StopMessageLiveLocationParams {
617 target: EditTarget::Inline {
618 inline_message_id: inline_message_id.into(),
619 },
620 reply_markup: None,
621 },
622 }
623 }
624 pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
626 self.params.reply_markup = Some(m);
627 self
628 }
629}
630
631impl_into_future!(StopMessageLiveLocation, Message, "stopMessageLiveLocation");