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::rich_message::InputRichMessage;
10use rustigram_types::user::ChatId;
11
12use crate::client::BotClient;
13use crate::error::Result;
14
15macro_rules! impl_into_future {
19 ($builder:ident, $return_ty:ty, $method:literal) => {
20 impl IntoFuture for $builder {
21 type Output = Result<$return_ty>;
22 type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
23
24 fn into_future(self) -> Self::IntoFuture {
25 Box::pin(async move { self.client.post_json($method, &self.params).await })
26 }
27 }
28 };
29}
30
31#[derive(Serialize)]
33#[serde(untagged)]
34pub enum EditTarget {
36 Chat {
38 chat_id: ChatId,
40 message_id: i64,
42 },
43 Inline {
45 inline_message_id: String,
47 },
48}
49
50#[derive(Serialize)]
53struct EditMessageTextParams {
54 #[serde(flatten)]
55 target: EditTarget,
56 #[serde(skip_serializing_if = "Option::is_none")]
58 text: Option<String>,
59 #[serde(skip_serializing_if = "Option::is_none")]
61 rich_message: Option<InputRichMessage>,
62 #[serde(skip_serializing_if = "Option::is_none")]
63 business_connection_id: Option<String>,
64 #[serde(skip_serializing_if = "Option::is_none")]
65 parse_mode: Option<ParseMode>,
66 #[serde(skip_serializing_if = "Option::is_none")]
67 entities: Option<Vec<MessageEntity>>,
68 #[serde(skip_serializing_if = "Option::is_none")]
69 link_preview_options: Option<LinkPreviewOptions>,
70 #[serde(skip_serializing_if = "Option::is_none")]
71 reply_markup: Option<InlineKeyboardMarkup>,
72}
73
74pub struct EditMessageText {
76 client: BotClient,
77 params: EditMessageTextParams,
78}
79
80impl EditMessageText {
81 pub(crate) fn in_chat(
82 client: BotClient,
83 chat_id: impl Into<ChatId>,
84 message_id: i64,
85 text: impl Into<String>,
86 ) -> Self {
87 Self {
88 client,
89 params: EditMessageTextParams {
90 target: EditTarget::Chat {
91 chat_id: chat_id.into(),
92 message_id,
93 },
94 text: Some(text.into()),
95 rich_message: None,
96 business_connection_id: None,
97 parse_mode: None,
98 entities: None,
99 link_preview_options: None,
100 reply_markup: None,
101 },
102 }
103 }
104 pub(crate) fn inline(
105 client: BotClient,
106 inline_message_id: impl Into<String>,
107 text: impl Into<String>,
108 ) -> Self {
109 Self {
110 client,
111 params: EditMessageTextParams {
112 target: EditTarget::Inline {
113 inline_message_id: inline_message_id.into(),
114 },
115 text: Some(text.into()),
116 rich_message: None,
117 business_connection_id: None,
118 parse_mode: None,
119 entities: None,
120 link_preview_options: None,
121 reply_markup: None,
122 },
123 }
124 }
125 pub(crate) fn in_chat_rich(
127 client: BotClient,
128 chat_id: impl Into<ChatId>,
129 message_id: i64,
130 rich_message: InputRichMessage,
131 ) -> Self {
132 Self {
133 client,
134 params: EditMessageTextParams {
135 target: EditTarget::Chat {
136 chat_id: chat_id.into(),
137 message_id,
138 },
139 text: None,
140 rich_message: Some(rich_message),
141 business_connection_id: None,
142 parse_mode: None,
143 entities: None,
144 link_preview_options: None,
145 reply_markup: None,
146 },
147 }
148 }
149 pub(crate) fn inline_rich(
151 client: BotClient,
152 inline_message_id: impl Into<String>,
153 rich_message: InputRichMessage,
154 ) -> Self {
155 Self {
156 client,
157 params: EditMessageTextParams {
158 target: EditTarget::Inline {
159 inline_message_id: inline_message_id.into(),
160 },
161 text: None,
162 rich_message: Some(rich_message),
163 business_connection_id: None,
164 parse_mode: None,
165 entities: None,
166 link_preview_options: None,
167 reply_markup: None,
168 },
169 }
170 }
171 pub fn parse_mode(mut self, m: ParseMode) -> Self {
173 self.params.parse_mode = Some(m);
174 self
175 }
176 pub fn entities(mut self, e: Vec<MessageEntity>) -> Self {
178 self.params.entities = Some(e);
179 self
180 }
181 pub fn link_preview_options(mut self, o: LinkPreviewOptions) -> Self {
183 self.params.link_preview_options = Some(o);
184 self
185 }
186 pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
188 self.params.reply_markup = Some(m);
189 self
190 }
191}
192
193impl_into_future!(EditMessageText, Message, "editMessageText");
194
195#[derive(Serialize)]
198struct EditMessageCaptionParams {
199 #[serde(flatten)]
200 target: EditTarget,
201 #[serde(skip_serializing_if = "Option::is_none")]
202 business_connection_id: Option<String>,
203 #[serde(skip_serializing_if = "Option::is_none")]
204 caption: Option<String>,
205 #[serde(skip_serializing_if = "Option::is_none")]
206 parse_mode: Option<ParseMode>,
207 #[serde(skip_serializing_if = "Option::is_none")]
208 caption_entities: Option<Vec<MessageEntity>>,
209 #[serde(skip_serializing_if = "Option::is_none")]
210 show_caption_above_media: Option<bool>,
211 #[serde(skip_serializing_if = "Option::is_none")]
212 reply_markup: Option<InlineKeyboardMarkup>,
213}
214
215pub struct EditMessageCaption {
217 client: BotClient,
218 params: EditMessageCaptionParams,
219}
220
221impl EditMessageCaption {
222 pub(crate) fn in_chat(client: BotClient, chat_id: impl Into<ChatId>, message_id: i64) -> Self {
223 Self {
224 client,
225 params: EditMessageCaptionParams {
226 target: EditTarget::Chat {
227 chat_id: chat_id.into(),
228 message_id,
229 },
230 business_connection_id: None,
231 caption: None,
232 parse_mode: None,
233 caption_entities: None,
234 show_caption_above_media: None,
235 reply_markup: None,
236 },
237 }
238 }
239 pub(crate) fn inline(client: BotClient, inline_message_id: impl Into<String>) -> Self {
240 Self {
241 client,
242 params: EditMessageCaptionParams {
243 target: EditTarget::Inline {
244 inline_message_id: inline_message_id.into(),
245 },
246 business_connection_id: None,
247 caption: None,
248 parse_mode: None,
249 caption_entities: None,
250 show_caption_above_media: None,
251 reply_markup: None,
252 },
253 }
254 }
255 pub fn caption(mut self, c: impl Into<String>) -> Self {
257 self.params.caption = Some(c.into());
258 self
259 }
260 pub fn parse_mode(mut self, m: ParseMode) -> Self {
262 self.params.parse_mode = Some(m);
263 self
264 }
265 pub fn show_caption_above_media(mut self, v: bool) -> Self {
267 self.params.show_caption_above_media = Some(v);
268 self
269 }
270 pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
272 self.params.reply_markup = Some(m);
273 self
274 }
275}
276
277impl_into_future!(EditMessageCaption, Message, "editMessageCaption");
278
279#[derive(Serialize)]
282struct EditMessageMediaParams {
283 #[serde(flatten)]
284 target: EditTarget,
285 media: serde_json::Value,
290 #[serde(skip_serializing_if = "Option::is_none")]
291 business_connection_id: Option<String>,
292 #[serde(skip_serializing_if = "Option::is_none")]
293 reply_markup: Option<InlineKeyboardMarkup>,
294}
295
296pub struct EditMessageMedia {
304 client: BotClient,
305 params: EditMessageMediaParams,
306}
307
308impl EditMessageMedia {
309 pub(crate) fn in_chat(
310 client: BotClient,
311 chat_id: impl Into<ChatId>,
312 message_id: i64,
313 media: serde_json::Value,
314 ) -> Self {
315 Self {
316 client,
317 params: EditMessageMediaParams {
318 target: EditTarget::Chat {
319 chat_id: chat_id.into(),
320 message_id,
321 },
322 media,
323 business_connection_id: None,
324 reply_markup: None,
325 },
326 }
327 }
328 pub(crate) fn inline(
329 client: BotClient,
330 inline_message_id: impl Into<String>,
331 media: serde_json::Value,
332 ) -> Self {
333 Self {
334 client,
335 params: EditMessageMediaParams {
336 target: EditTarget::Inline {
337 inline_message_id: inline_message_id.into(),
338 },
339 media,
340 business_connection_id: None,
341 reply_markup: None,
342 },
343 }
344 }
345 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
347 self.params.business_connection_id = Some(id.into());
348 self
349 }
350 pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
352 self.params.reply_markup = Some(m);
353 self
354 }
355}
356
357impl_into_future!(EditMessageMedia, Message, "editMessageMedia");
358
359#[derive(Serialize)]
362struct EditMessageReplyMarkupParams {
363 #[serde(flatten)]
364 target: EditTarget,
365 #[serde(skip_serializing_if = "Option::is_none")]
366 business_connection_id: Option<String>,
367 #[serde(skip_serializing_if = "Option::is_none")]
368 reply_markup: Option<InlineKeyboardMarkup>,
369}
370
371pub struct EditMessageReplyMarkup {
373 client: BotClient,
374 params: EditMessageReplyMarkupParams,
375}
376
377impl EditMessageReplyMarkup {
378 pub(crate) fn in_chat(client: BotClient, chat_id: impl Into<ChatId>, message_id: i64) -> Self {
379 Self {
380 client,
381 params: EditMessageReplyMarkupParams {
382 target: EditTarget::Chat {
383 chat_id: chat_id.into(),
384 message_id,
385 },
386 business_connection_id: None,
387 reply_markup: None,
388 },
389 }
390 }
391 pub(crate) fn inline(client: BotClient, inline_message_id: impl Into<String>) -> Self {
392 Self {
393 client,
394 params: EditMessageReplyMarkupParams {
395 target: EditTarget::Inline {
396 inline_message_id: inline_message_id.into(),
397 },
398 business_connection_id: None,
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 pub fn remove_markup(mut self) -> Self {
410 self.params.reply_markup = None;
411 self
412 }
413}
414
415impl_into_future!(EditMessageReplyMarkup, Message, "editMessageReplyMarkup");
416
417#[derive(Serialize)]
420struct EditEphemeralMessageTextParams {
421 chat_id: ChatId,
422 receiver_user_id: i64,
423 ephemeral_message_id: i64,
424 text: String,
425 #[serde(skip_serializing_if = "Option::is_none")]
426 parse_mode: Option<ParseMode>,
427 #[serde(skip_serializing_if = "Option::is_none")]
428 entities: Option<Vec<MessageEntity>>,
429 #[serde(skip_serializing_if = "Option::is_none")]
430 reply_markup: Option<InlineKeyboardMarkup>,
431}
432
433pub struct EditEphemeralMessageText {
438 client: BotClient,
439 params: EditEphemeralMessageTextParams,
440}
441
442impl EditEphemeralMessageText {
443 pub(crate) fn new(
444 client: BotClient,
445 chat_id: impl Into<ChatId>,
446 receiver_user_id: i64,
447 ephemeral_message_id: i64,
448 text: impl Into<String>,
449 ) -> Self {
450 Self {
451 client,
452 params: EditEphemeralMessageTextParams {
453 chat_id: chat_id.into(),
454 receiver_user_id,
455 ephemeral_message_id,
456 text: text.into(),
457 parse_mode: None,
458 entities: None,
459 reply_markup: None,
460 },
461 }
462 }
463 pub fn parse_mode(mut self, m: ParseMode) -> Self {
465 self.params.parse_mode = Some(m);
466 self
467 }
468 pub fn entities(mut self, e: Vec<MessageEntity>) -> Self {
470 self.params.entities = Some(e);
471 self
472 }
473 pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
475 self.params.reply_markup = Some(m);
476 self
477 }
478}
479
480impl_into_future!(EditEphemeralMessageText, bool, "editEphemeralMessageText");
481
482#[derive(Serialize)]
485struct EditEphemeralMessageCaptionParams {
486 chat_id: ChatId,
487 receiver_user_id: i64,
488 ephemeral_message_id: i64,
489 #[serde(skip_serializing_if = "Option::is_none")]
490 caption: Option<String>,
491 #[serde(skip_serializing_if = "Option::is_none")]
492 parse_mode: Option<ParseMode>,
493 #[serde(skip_serializing_if = "Option::is_none")]
494 caption_entities: Option<Vec<MessageEntity>>,
495 #[serde(skip_serializing_if = "Option::is_none")]
496 reply_markup: Option<InlineKeyboardMarkup>,
497}
498
499pub struct EditEphemeralMessageCaption {
504 client: BotClient,
505 params: EditEphemeralMessageCaptionParams,
506}
507
508impl EditEphemeralMessageCaption {
509 pub(crate) fn new(
510 client: BotClient,
511 chat_id: impl Into<ChatId>,
512 receiver_user_id: i64,
513 ephemeral_message_id: i64,
514 ) -> Self {
515 Self {
516 client,
517 params: EditEphemeralMessageCaptionParams {
518 chat_id: chat_id.into(),
519 receiver_user_id,
520 ephemeral_message_id,
521 caption: None,
522 parse_mode: None,
523 caption_entities: None,
524 reply_markup: None,
525 },
526 }
527 }
528 pub fn caption(mut self, c: impl Into<String>) -> Self {
530 self.params.caption = Some(c.into());
531 self
532 }
533 pub fn parse_mode(mut self, m: ParseMode) -> Self {
535 self.params.parse_mode = Some(m);
536 self
537 }
538 pub fn caption_entities(mut self, e: Vec<MessageEntity>) -> Self {
540 self.params.caption_entities = Some(e);
541 self
542 }
543 pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
545 self.params.reply_markup = Some(m);
546 self
547 }
548}
549
550impl_into_future!(
551 EditEphemeralMessageCaption,
552 bool,
553 "editEphemeralMessageCaption"
554);
555
556#[derive(Serialize)]
559struct EditEphemeralMessageReplyMarkupParams {
560 chat_id: ChatId,
561 receiver_user_id: i64,
562 ephemeral_message_id: i64,
563 #[serde(skip_serializing_if = "Option::is_none")]
564 reply_markup: Option<InlineKeyboardMarkup>,
565}
566
567pub struct EditEphemeralMessageReplyMarkup {
572 client: BotClient,
573 params: EditEphemeralMessageReplyMarkupParams,
574}
575
576impl EditEphemeralMessageReplyMarkup {
577 pub(crate) fn new(
578 client: BotClient,
579 chat_id: impl Into<ChatId>,
580 receiver_user_id: i64,
581 ephemeral_message_id: i64,
582 ) -> Self {
583 Self {
584 client,
585 params: EditEphemeralMessageReplyMarkupParams {
586 chat_id: chat_id.into(),
587 receiver_user_id,
588 ephemeral_message_id,
589 reply_markup: None,
590 },
591 }
592 }
593 pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
595 self.params.reply_markup = Some(m);
596 self
597 }
598 pub fn remove_markup(mut self) -> Self {
600 self.params.reply_markup = None;
601 self
602 }
603}
604
605impl_into_future!(
606 EditEphemeralMessageReplyMarkup,
607 bool,
608 "editEphemeralMessageReplyMarkup"
609);
610
611#[derive(Serialize)]
614struct EditMessageChecklistParams {
615 business_connection_id: String,
616 chat_id: i64,
617 message_id: i64,
618 checklist: InputChecklist,
619 #[serde(skip_serializing_if = "Option::is_none")]
620 reply_markup: Option<InlineKeyboardMarkup>,
621}
622
623pub struct EditMessageChecklist {
628 client: BotClient,
629 params: EditMessageChecklistParams,
630}
631
632impl EditMessageChecklist {
633 pub(crate) fn new(
634 client: BotClient,
635 business_connection_id: impl Into<String>,
636 chat_id: i64,
637 message_id: i64,
638 checklist: InputChecklist,
639 ) -> Self {
640 Self {
641 client,
642 params: EditMessageChecklistParams {
643 business_connection_id: business_connection_id.into(),
644 chat_id,
645 message_id,
646 checklist,
647 reply_markup: None,
648 },
649 }
650 }
651 pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
653 self.params.reply_markup = Some(m);
654 self
655 }
656}
657
658impl_into_future!(EditMessageChecklist, Message, "editMessageChecklist");
659
660#[derive(Serialize)]
663struct ApproveSuggestedPostParams {
664 chat_id: i64,
665 message_id: i64,
666 #[serde(skip_serializing_if = "Option::is_none")]
667 send_date: Option<i64>,
668}
669
670pub struct ApproveSuggestedPost {
675 client: BotClient,
676 params: ApproveSuggestedPostParams,
677}
678
679impl ApproveSuggestedPost {
680 pub(crate) fn new(client: BotClient, chat_id: i64, message_id: i64) -> Self {
681 Self {
682 client,
683 params: ApproveSuggestedPostParams {
684 chat_id,
685 message_id,
686 send_date: None,
687 },
688 }
689 }
690 pub fn send_date(mut self, ts: i64) -> Self {
694 self.params.send_date = Some(ts);
695 self
696 }
697}
698
699impl_into_future!(ApproveSuggestedPost, bool, "approveSuggestedPost");
700
701#[derive(Serialize)]
704struct DeclineSuggestedPostParams {
705 chat_id: i64,
706 message_id: i64,
707 #[serde(skip_serializing_if = "Option::is_none")]
708 comment: Option<String>,
709}
710
711pub struct DeclineSuggestedPost {
716 client: BotClient,
717 params: DeclineSuggestedPostParams,
718}
719
720impl DeclineSuggestedPost {
721 pub(crate) fn new(client: BotClient, chat_id: i64, message_id: i64) -> Self {
722 Self {
723 client,
724 params: DeclineSuggestedPostParams {
725 chat_id,
726 message_id,
727 comment: None,
728 },
729 }
730 }
731 pub fn comment(mut self, c: impl Into<String>) -> Self {
733 self.params.comment = Some(c.into());
734 self
735 }
736}
737
738impl_into_future!(DeclineSuggestedPost, bool, "declineSuggestedPost");
739
740#[derive(Serialize)]
743struct EditMessageLiveLocationParams {
744 #[serde(flatten)]
745 target: EditTarget,
746 latitude: f64,
747 longitude: f64,
748 #[serde(skip_serializing_if = "Option::is_none")]
749 live_period: Option<u32>,
750 #[serde(skip_serializing_if = "Option::is_none")]
751 horizontal_accuracy: Option<f64>,
752 #[serde(skip_serializing_if = "Option::is_none")]
753 heading: Option<u16>,
754 #[serde(skip_serializing_if = "Option::is_none")]
755 proximity_alert_radius: Option<u32>,
756 #[serde(skip_serializing_if = "Option::is_none")]
757 reply_markup: Option<InlineKeyboardMarkup>,
758}
759
760pub struct EditMessageLiveLocation {
762 client: BotClient,
763 params: EditMessageLiveLocationParams,
764}
765
766impl EditMessageLiveLocation {
767 pub(crate) fn in_chat(
768 client: BotClient,
769 chat_id: impl Into<ChatId>,
770 message_id: i64,
771 latitude: f64,
772 longitude: f64,
773 ) -> Self {
774 Self {
775 client,
776 params: EditMessageLiveLocationParams {
777 target: EditTarget::Chat {
778 chat_id: chat_id.into(),
779 message_id,
780 },
781 latitude,
782 longitude,
783 live_period: None,
784 horizontal_accuracy: None,
785 heading: None,
786 proximity_alert_radius: None,
787 reply_markup: None,
788 },
789 }
790 }
791 pub(crate) fn inline(
792 client: BotClient,
793 inline_message_id: impl Into<String>,
794 latitude: f64,
795 longitude: f64,
796 ) -> Self {
797 Self {
798 client,
799 params: EditMessageLiveLocationParams {
800 target: EditTarget::Inline {
801 inline_message_id: inline_message_id.into(),
802 },
803 latitude,
804 longitude,
805 live_period: None,
806 horizontal_accuracy: None,
807 heading: None,
808 proximity_alert_radius: None,
809 reply_markup: None,
810 },
811 }
812 }
813 pub fn live_period(mut self, v: u32) -> Self {
815 self.params.live_period = Some(v);
816 self
817 }
818 pub fn heading(mut self, v: u16) -> Self {
820 self.params.heading = Some(v);
821 self
822 }
823 pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
825 self.params.reply_markup = Some(m);
826 self
827 }
828}
829
830impl_into_future!(EditMessageLiveLocation, Message, "editMessageLiveLocation");
831
832#[derive(Serialize)]
835struct StopMessageLiveLocationParams {
836 #[serde(flatten)]
837 target: EditTarget,
838 #[serde(skip_serializing_if = "Option::is_none")]
839 reply_markup: Option<InlineKeyboardMarkup>,
840}
841
842pub struct StopMessageLiveLocation {
844 client: BotClient,
845 params: StopMessageLiveLocationParams,
846}
847
848impl StopMessageLiveLocation {
849 pub(crate) fn in_chat(client: BotClient, chat_id: impl Into<ChatId>, message_id: i64) -> Self {
850 Self {
851 client,
852 params: StopMessageLiveLocationParams {
853 target: EditTarget::Chat {
854 chat_id: chat_id.into(),
855 message_id,
856 },
857 reply_markup: None,
858 },
859 }
860 }
861 pub(crate) fn inline(client: BotClient, inline_message_id: impl Into<String>) -> Self {
862 Self {
863 client,
864 params: StopMessageLiveLocationParams {
865 target: EditTarget::Inline {
866 inline_message_id: inline_message_id.into(),
867 },
868 reply_markup: None,
869 },
870 }
871 }
872 pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
874 self.params.reply_markup = Some(m);
875 self
876 }
877}
878
879impl_into_future!(StopMessageLiveLocation, Message, "stopMessageLiveLocation");