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 EditMessageChecklistParams {
421 business_connection_id: String,
422 chat_id: i64,
423 message_id: i64,
424 checklist: InputChecklist,
425 #[serde(skip_serializing_if = "Option::is_none")]
426 reply_markup: Option<InlineKeyboardMarkup>,
427}
428
429pub struct EditMessageChecklist {
434 client: BotClient,
435 params: EditMessageChecklistParams,
436}
437
438impl EditMessageChecklist {
439 pub(crate) fn new(
440 client: BotClient,
441 business_connection_id: impl Into<String>,
442 chat_id: i64,
443 message_id: i64,
444 checklist: InputChecklist,
445 ) -> Self {
446 Self {
447 client,
448 params: EditMessageChecklistParams {
449 business_connection_id: business_connection_id.into(),
450 chat_id,
451 message_id,
452 checklist,
453 reply_markup: None,
454 },
455 }
456 }
457 pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
459 self.params.reply_markup = Some(m);
460 self
461 }
462}
463
464impl_into_future!(EditMessageChecklist, Message, "editMessageChecklist");
465
466#[derive(Serialize)]
469struct ApproveSuggestedPostParams {
470 chat_id: i64,
471 message_id: i64,
472 #[serde(skip_serializing_if = "Option::is_none")]
473 send_date: Option<i64>,
474}
475
476pub struct ApproveSuggestedPost {
481 client: BotClient,
482 params: ApproveSuggestedPostParams,
483}
484
485impl ApproveSuggestedPost {
486 pub(crate) fn new(client: BotClient, chat_id: i64, message_id: i64) -> Self {
487 Self {
488 client,
489 params: ApproveSuggestedPostParams {
490 chat_id,
491 message_id,
492 send_date: None,
493 },
494 }
495 }
496 pub fn send_date(mut self, ts: i64) -> Self {
500 self.params.send_date = Some(ts);
501 self
502 }
503}
504
505impl_into_future!(ApproveSuggestedPost, bool, "approveSuggestedPost");
506
507#[derive(Serialize)]
510struct DeclineSuggestedPostParams {
511 chat_id: i64,
512 message_id: i64,
513 #[serde(skip_serializing_if = "Option::is_none")]
514 comment: Option<String>,
515}
516
517pub struct DeclineSuggestedPost {
522 client: BotClient,
523 params: DeclineSuggestedPostParams,
524}
525
526impl DeclineSuggestedPost {
527 pub(crate) fn new(client: BotClient, chat_id: i64, message_id: i64) -> Self {
528 Self {
529 client,
530 params: DeclineSuggestedPostParams {
531 chat_id,
532 message_id,
533 comment: None,
534 },
535 }
536 }
537 pub fn comment(mut self, c: impl Into<String>) -> Self {
539 self.params.comment = Some(c.into());
540 self
541 }
542}
543
544impl_into_future!(DeclineSuggestedPost, bool, "declineSuggestedPost");
545
546#[derive(Serialize)]
549struct EditMessageLiveLocationParams {
550 #[serde(flatten)]
551 target: EditTarget,
552 latitude: f64,
553 longitude: f64,
554 #[serde(skip_serializing_if = "Option::is_none")]
555 live_period: Option<u32>,
556 #[serde(skip_serializing_if = "Option::is_none")]
557 horizontal_accuracy: Option<f64>,
558 #[serde(skip_serializing_if = "Option::is_none")]
559 heading: Option<u16>,
560 #[serde(skip_serializing_if = "Option::is_none")]
561 proximity_alert_radius: Option<u32>,
562 #[serde(skip_serializing_if = "Option::is_none")]
563 reply_markup: Option<InlineKeyboardMarkup>,
564}
565
566pub struct EditMessageLiveLocation {
568 client: BotClient,
569 params: EditMessageLiveLocationParams,
570}
571
572impl EditMessageLiveLocation {
573 pub(crate) fn in_chat(
574 client: BotClient,
575 chat_id: impl Into<ChatId>,
576 message_id: i64,
577 latitude: f64,
578 longitude: f64,
579 ) -> Self {
580 Self {
581 client,
582 params: EditMessageLiveLocationParams {
583 target: EditTarget::Chat {
584 chat_id: chat_id.into(),
585 message_id,
586 },
587 latitude,
588 longitude,
589 live_period: None,
590 horizontal_accuracy: None,
591 heading: None,
592 proximity_alert_radius: None,
593 reply_markup: None,
594 },
595 }
596 }
597 pub(crate) fn inline(
598 client: BotClient,
599 inline_message_id: impl Into<String>,
600 latitude: f64,
601 longitude: f64,
602 ) -> Self {
603 Self {
604 client,
605 params: EditMessageLiveLocationParams {
606 target: EditTarget::Inline {
607 inline_message_id: inline_message_id.into(),
608 },
609 latitude,
610 longitude,
611 live_period: None,
612 horizontal_accuracy: None,
613 heading: None,
614 proximity_alert_radius: None,
615 reply_markup: None,
616 },
617 }
618 }
619 pub fn live_period(mut self, v: u32) -> Self {
621 self.params.live_period = Some(v);
622 self
623 }
624 pub fn heading(mut self, v: u16) -> Self {
626 self.params.heading = Some(v);
627 self
628 }
629 pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
631 self.params.reply_markup = Some(m);
632 self
633 }
634}
635
636impl_into_future!(EditMessageLiveLocation, Message, "editMessageLiveLocation");
637
638#[derive(Serialize)]
641struct StopMessageLiveLocationParams {
642 #[serde(flatten)]
643 target: EditTarget,
644 #[serde(skip_serializing_if = "Option::is_none")]
645 reply_markup: Option<InlineKeyboardMarkup>,
646}
647
648pub struct StopMessageLiveLocation {
650 client: BotClient,
651 params: StopMessageLiveLocationParams,
652}
653
654impl StopMessageLiveLocation {
655 pub(crate) fn in_chat(client: BotClient, chat_id: impl Into<ChatId>, message_id: i64) -> Self {
656 Self {
657 client,
658 params: StopMessageLiveLocationParams {
659 target: EditTarget::Chat {
660 chat_id: chat_id.into(),
661 message_id,
662 },
663 reply_markup: None,
664 },
665 }
666 }
667 pub(crate) fn inline(client: BotClient, inline_message_id: impl Into<String>) -> Self {
668 Self {
669 client,
670 params: StopMessageLiveLocationParams {
671 target: EditTarget::Inline {
672 inline_message_id: inline_message_id.into(),
673 },
674 reply_markup: None,
675 },
676 }
677 }
678 pub fn reply_markup(mut self, m: InlineKeyboardMarkup) -> Self {
680 self.params.reply_markup = Some(m);
681 self
682 }
683}
684
685impl_into_future!(StopMessageLiveLocation, Message, "stopMessageLiveLocation");