Skip to main content

ronami_core/adaptors/
parse_mode.rs

1use std::future::IntoFuture;
2
3use url::Url;
4
5use crate::{
6    payloads::{
7        AnswerInlineQuery, AnswerWebAppQuery, CopyMessage, EditMessageCaption,
8        EditMessageCaptionInline, EditMessageChecklist, EditMessageMedia, EditMessageMediaInline,
9        EditMessageText, EditMessageTextInline, EditStory, GiftPremiumSubscription, PostStory,
10        SavePreparedInlineMessage, SendAnimation, SendAudio, SendChecklist, SendDocument, SendGift,
11        SendGiftChat, SendLivePhoto, SendMediaGroup, SendMessage, SendMessageDraft, SendPaidMedia,
12        SendPhoto, SendPoll, SendVideo, SendVoice,
13    },
14    prelude::Requester,
15    requests::{HasPayload, Output, Request},
16    types::*,
17};
18
19/// Default parse mode adaptor, see
20/// [`RequesterExt::parse_mode`](crate::requests::RequesterExt::parse_mode).
21#[derive(Clone, Debug)]
22pub struct DefaultParseMode<B> {
23    bot: B,
24    mode: ParseMode,
25}
26
27/// Request returned by [`DefaultParseMode`] methods.
28#[derive(Clone)]
29pub struct DefaultParseModeRequest<R> {
30    req: R,
31    mode: ParseMode,
32}
33
34impl<B> DefaultParseMode<B> {
35    /// Creates new [`DefaultParseMode`].
36    ///
37    /// Note: it's recommended to use [`RequesterExt::parse_mode`] instead.
38    ///
39    /// [`RequesterExt::parse_mode`]: crate::requests::RequesterExt::parse_mode
40    pub fn new(bot: B, parse_mode: ParseMode) -> Self {
41        Self { bot, mode: parse_mode }
42    }
43
44    /// Allows to access the inner bot.
45    pub fn inner(&self) -> &B {
46        &self.bot
47    }
48
49    /// Unwraps the inner bot.
50    pub fn into_inner(self) -> B {
51        self.bot
52    }
53
54    /// Returns currently used [`ParseMode`].
55    pub fn parse_mode(&self) -> ParseMode {
56        self.mode
57    }
58}
59
60impl<R> Request for DefaultParseModeRequest<R>
61where
62    R: Request + Clone,
63    R::Payload: VisitParseModes,
64{
65    type Err = R::Err;
66    type Send = R::Send;
67    type SendRef = R::Send;
68
69    // Required methods
70    fn send(mut self) -> Self::Send {
71        self.req.payload_mut().visit_parse_modes(|mode| _ = mode.get_or_insert(self.mode));
72        self.req.send()
73    }
74
75    fn send_ref(&self) -> Self::SendRef {
76        // There is no other way to change the payload, given a `&self` :(
77        self.clone().send()
78    }
79}
80
81impl<R> IntoFuture for DefaultParseModeRequest<R>
82where
83    Self: Request,
84{
85    type Output = Result<Output<Self>, <Self as Request>::Err>;
86    type IntoFuture = <Self as Request>::Send;
87
88    fn into_future(self) -> Self::IntoFuture {
89        self.send()
90    }
91}
92
93impl<R> HasPayload for DefaultParseModeRequest<R>
94where
95    R: Request,
96{
97    type Payload = R::Payload;
98
99    fn payload_mut(&mut self) -> &mut Self::Payload {
100        self.req.payload_mut()
101    }
102
103    fn payload_ref(&self) -> &Self::Payload {
104        self.req.payload_ref()
105    }
106}
107
108macro_rules! f {
109    ($m:ident $this:ident ($($arg:ident : $T:ty),*)) => {
110        {
111            let req = $this.inner().$m($($arg),*);
112            DefaultParseModeRequest { req, mode: $this.mode }
113        }
114    };
115}
116
117macro_rules! fty {
118    ($T:ident) => {
119        DefaultParseModeRequest<B::$T>
120    };
121}
122
123macro_rules! ftyid {
124    ($T:ident) => {
125        B::$T
126    };
127}
128
129macro_rules! fid {
130    ($m:ident $this:ident ($($arg:ident : $T:ty),*)) => {
131        $this.inner().$m($($arg),*)
132    };
133}
134
135impl<B> Requester for DefaultParseMode<B>
136where
137    B: Requester,
138    B::SendMessage: Clone,
139    B::SendMessageDraft: Clone,
140    B::SendPhoto: Clone,
141    B::SendVideo: Clone,
142    B::SendAudio: Clone,
143    B::SendDocument: Clone,
144    B::SendAnimation: Clone,
145    B::SendVoice: Clone,
146    B::SendLivePhoto: Clone,
147    B::EditMessageText: Clone,
148    B::EditMessageTextInline: Clone,
149    B::EditMessageCaption: Clone,
150    B::EditMessageCaptionInline: Clone,
151    B::SendPoll: Clone,
152    B::SendChecklist: Clone,
153    B::CopyMessage: Clone,
154    B::PostStory: Clone,
155    B::EditStory: Clone,
156    B::AnswerInlineQuery: Clone,
157    B::AnswerWebAppQuery: Clone,
158    B::SavePreparedInlineMessage: Clone,
159    B::EditMessageMedia: Clone,
160    B::EditMessageMediaInline: Clone,
161    B::EditMessageChecklist: Clone,
162    B::SendPaidMedia: Clone,
163    B::SendMediaGroup: Clone,
164    B::GiftPremiumSubscription: Clone,
165    B::SendGift: Clone,
166    B::SendGiftChat: Clone,
167{
168    type Err = B::Err;
169
170    requester_forward! {
171        send_message,
172        send_message_draft,
173        send_photo,
174        send_video,
175        send_audio,
176        send_document,
177        send_animation,
178        send_voice,
179        send_poll,
180        send_checklist,
181        edit_message_text,
182        edit_message_text_inline,
183        edit_message_caption,
184        edit_message_caption_inline,
185        edit_message_checklist,
186        copy_message,
187        post_story,
188        edit_story,
189        answer_inline_query,
190        answer_web_app_query,
191        save_prepared_inline_message,
192        send_paid_media,
193        send_media_group,
194        edit_message_media,
195        edit_message_media_inline,
196        gift_premium_subscription,
197        send_gift,
198        send_gift_chat,
199        => f, fty
200    }
201
202    requester_forward! {
203        get_me,
204        log_out,
205        close,
206        get_updates,
207        set_webhook,
208        delete_webhook,
209        get_webhook_info,
210        forward_message,
211        forward_messages,
212        copy_messages,
213        send_video_note,
214        send_location,
215        edit_message_live_location,
216        edit_message_live_location_inline,
217        stop_message_live_location,
218        stop_message_live_location_inline,
219        send_venue,
220        send_contact,
221        send_dice,
222        send_chat_action,
223        set_message_reaction,
224        get_user_profile_photos,
225        get_user_profile_audios,
226        set_user_emoji_status,
227        get_file,
228        kick_chat_member,
229        ban_chat_member,
230        unban_chat_member,
231        restrict_chat_member,
232        promote_chat_member,
233        set_chat_administrator_custom_title,
234        set_chat_member_tag,
235        ban_chat_sender_chat,
236        unban_chat_sender_chat,
237        set_chat_permissions,
238        export_chat_invite_link,
239        create_chat_invite_link,
240        edit_chat_invite_link,
241        create_chat_subscription_invite_link,
242        edit_chat_subscription_invite_link,
243        revoke_chat_invite_link,
244        set_chat_photo,
245        delete_chat_photo,
246        set_chat_title,
247        set_chat_description,
248        pin_chat_message,
249        unpin_chat_message,
250        unpin_all_chat_messages,
251        leave_chat,
252        get_chat,
253        get_chat_administrators,
254        get_chat_members_count,
255        get_chat_member_count,
256        get_chat_member,
257        set_chat_sticker_set,
258        delete_chat_sticker_set,
259        get_forum_topic_icon_stickers,
260        create_forum_topic,
261        edit_forum_topic,
262        close_forum_topic,
263        reopen_forum_topic,
264        delete_forum_topic,
265        unpin_all_forum_topic_messages,
266        edit_general_forum_topic,
267        close_general_forum_topic,
268        reopen_general_forum_topic,
269        hide_general_forum_topic,
270        unhide_general_forum_topic,
271        unpin_all_general_forum_topic_messages,
272        answer_callback_query,
273        get_user_chat_boosts,
274        set_my_commands,
275        get_business_connection,
276        get_my_commands,
277        set_my_name,
278        get_my_name,
279        set_my_description,
280        get_my_description,
281        set_my_short_description,
282        get_my_short_description,
283        set_my_profile_photo,
284        remove_my_profile_photo,
285        get_managed_bot_token,
286        replace_managed_bot_token,
287        save_prepared_keyboard_button,
288        send_live_photo,
289        get_user_personal_chat_messages,
290        answer_guest_query,
291        get_managed_bot_access_settings,
292        set_managed_bot_access_settings,
293        delete_message_reaction,
294        delete_all_message_reactions,
295        set_chat_menu_button,
296        get_chat_menu_button,
297        set_my_default_administrator_rights,
298        get_my_default_administrator_rights,
299        delete_my_commands,
300        edit_message_reply_markup,
301        edit_message_reply_markup_inline,
302        stop_poll,
303        approve_suggested_post,
304        decline_suggested_post,
305        delete_message,
306        delete_messages,
307        send_sticker,
308        get_sticker_set,
309        get_custom_emoji_stickers,
310        upload_sticker_file,
311        create_new_sticker_set,
312        add_sticker_to_set,
313        set_sticker_position_in_set,
314        delete_sticker_from_set,
315        replace_sticker_in_set,
316        set_sticker_set_thumbnail,
317        set_custom_emoji_sticker_set_thumbnail,
318        set_sticker_set_title,
319        delete_sticker_set,
320        set_sticker_emoji_list,
321        set_sticker_keywords,
322        set_sticker_mask_position,
323        get_available_gifts,
324        verify_user,
325        verify_chat,
326        remove_user_verification,
327        remove_chat_verification,
328        read_business_message,
329        delete_business_messages,
330        set_business_account_name,
331        set_business_account_username,
332        set_business_account_bio,
333        set_business_account_profile_photo,
334        remove_business_account_profile_photo,
335        set_business_account_gift_settings,
336        get_business_account_star_balance,
337        transfer_business_account_stars,
338        get_business_account_gifts,
339        get_user_gifts,
340        get_chat_gifts,
341        repost_story,
342        convert_gift_to_stars,
343        upgrade_gift,
344        transfer_gift,
345        delete_story,
346        send_invoice,
347        create_invoice_link,
348        answer_shipping_query,
349        answer_pre_checkout_query,
350        get_my_star_balance,
351        get_star_transactions,
352        refund_star_payment,
353        edit_user_star_subscription,
354        set_passport_data_errors,
355        send_game,
356        set_game_score,
357        set_game_score_inline,
358        get_game_high_scores,
359        approve_chat_join_request,
360        decline_chat_join_request
361        => fid, ftyid
362    }
363}
364
365download_forward! {
366    B
367    DefaultParseMode<B>
368    { this => this.inner() }
369}
370
371trait VisitParseModes {
372    fn visit_parse_modes(&mut self, visitor: impl FnMut(&mut Option<ParseMode>));
373}
374
375macro_rules! impl_visit_parse_modes {
376    (
377        $(
378            $T:ty => [
379                $(
380                    $field:ident
381                ),*
382            ]
383            ,
384        )*
385    ) => {
386        $(
387            impl VisitParseModes for $T {
388                fn visit_parse_modes(&mut self, mut visitor: impl FnMut(&mut Option<ParseMode>)) {
389                    $(
390                        visitor(&mut self.$field);
391                    )*
392                }
393            }
394        )*
395    }
396}
397
398impl_visit_parse_modes! {
399    SendMessage => [parse_mode],
400    SendMessageDraft => [parse_mode],
401    SendPhoto => [parse_mode],
402    SendVideo => [parse_mode],
403    SendAudio => [parse_mode],
404    SendDocument => [parse_mode],
405    SendAnimation => [parse_mode],
406    SendVoice => [parse_mode],
407    SendLivePhoto => [parse_mode],
408    EditMessageText => [parse_mode],
409    EditMessageTextInline => [parse_mode],
410    EditMessageCaption => [parse_mode],
411    EditMessageCaptionInline => [parse_mode],
412    SendPaidMedia => [parse_mode],
413    GiftPremiumSubscription => [text_parse_mode],
414    SendGift => [text_parse_mode],
415    SendGiftChat => [text_parse_mode],
416    // FIXME: check if `parse_mode` changes anything if `.caption` is not set
417    //        (and if it does, maybe not call visitor if `self.caption.is_none()`)
418    CopyMessage => [parse_mode],
419    PostStory => [parse_mode],
420    EditStory => [parse_mode],
421    SendPoll => [explanation_parse_mode, description_parse_mode],
422}
423
424impl VisitParseModes for AnswerInlineQuery {
425    fn visit_parse_modes(&mut self, mut visitor: impl FnMut(&mut Option<ParseMode>)) {
426        self.results
427            .iter_mut()
428            .for_each(|result| visit_parse_modes_in_inline_query_result(result, &mut visitor))
429    }
430}
431
432impl VisitParseModes for AnswerWebAppQuery {
433    fn visit_parse_modes(&mut self, mut visitor: impl FnMut(&mut Option<ParseMode>)) {
434        visit_parse_modes_in_inline_query_result(&mut self.result, &mut visitor);
435    }
436}
437
438impl VisitParseModes for SavePreparedInlineMessage {
439    fn visit_parse_modes(&mut self, mut visitor: impl FnMut(&mut Option<ParseMode>)) {
440        visit_parse_modes_in_inline_query_result(&mut self.result, &mut visitor);
441    }
442}
443
444impl VisitParseModes for SendMediaGroup {
445    fn visit_parse_modes(&mut self, mut visitor: impl FnMut(&mut Option<ParseMode>)) {
446        self.media
447            .iter_mut()
448            .for_each(|media| visit_parse_modes_in_input_media(media, &mut visitor))
449    }
450}
451
452impl VisitParseModes for EditMessageMedia {
453    fn visit_parse_modes(&mut self, mut visitor: impl FnMut(&mut Option<ParseMode>)) {
454        visit_parse_modes_in_input_media(&mut self.media, &mut visitor);
455    }
456}
457
458impl VisitParseModes for EditMessageMediaInline {
459    fn visit_parse_modes(&mut self, mut visitor: impl FnMut(&mut Option<ParseMode>)) {
460        visit_parse_modes_in_input_media(&mut self.media, &mut visitor);
461    }
462}
463
464impl VisitParseModes for EditMessageChecklist {
465    fn visit_parse_modes(&mut self, mut visitor: impl FnMut(&mut Option<ParseMode>)) {
466        visitor(&mut self.checklist.parse_mode);
467    }
468}
469
470impl VisitParseModes for SendChecklist {
471    fn visit_parse_modes(&mut self, mut visitor: impl FnMut(&mut Option<ParseMode>)) {
472        visitor(&mut self.checklist.parse_mode);
473    }
474}
475
476fn visit_parse_modes_in_inline_query_result(
477    result: &mut InlineQueryResult,
478    visitor: &mut impl FnMut(&mut Option<ParseMode>),
479) {
480    use InlineQueryResult::*;
481
482    let parse_mode = match result {
483        // Simply contain `parse_mode`
484        CachedAudio(r) => &mut r.parse_mode,
485        CachedDocument(r) => &mut r.parse_mode,
486        CachedGif(r) => &mut r.parse_mode,
487        CachedMpeg4Gif(r) => &mut r.parse_mode,
488        CachedPhoto(r) => &mut r.parse_mode,
489        CachedVideo(r) => &mut r.parse_mode,
490        CachedVoice(r) => &mut r.parse_mode,
491        Audio(r) => &mut r.parse_mode,
492        Document(r) => &mut r.parse_mode,
493        Gif(r) => &mut r.parse_mode,
494        Mpeg4Gif(r) => &mut r.parse_mode,
495        Photo(r) => &mut r.parse_mode,
496        Video(r) => &mut r.parse_mode,
497        Voice(r) => &mut r.parse_mode,
498
499        // Can contain parse mode if `InputMessageContent::Text`
500        CachedSticker(r) => match &mut r.input_message_content {
501            Some(InputMessageContent::Text(t)) => &mut t.parse_mode,
502            _ => return,
503        },
504        Article(r) => match &mut r.input_message_content {
505            InputMessageContent::Text(t) => &mut t.parse_mode,
506            _ => return,
507        },
508        Contact(r) => match &mut r.input_message_content {
509            Some(InputMessageContent::Text(t)) => &mut t.parse_mode,
510            _ => return,
511        },
512        Location(r) => match &mut r.input_message_content {
513            Some(InputMessageContent::Text(t)) => &mut t.parse_mode,
514            _ => return,
515        },
516        Venue(r) => match &mut r.input_message_content {
517            Some(InputMessageContent::Text(t)) => &mut t.parse_mode,
518            _ => return,
519        },
520
521        // Can't contain `parse_mode` at all
522        Game(_r) => return,
523    };
524
525    visitor(parse_mode);
526}
527
528fn visit_parse_modes_in_input_media(
529    media: &mut InputMedia,
530    visitor: &mut impl FnMut(&mut Option<ParseMode>),
531) {
532    use InputMedia::*;
533
534    let parse_mode = match media {
535        Photo(m) => &mut m.parse_mode,
536        Video(m) => &mut m.parse_mode,
537        Animation(m) => &mut m.parse_mode,
538        Audio(m) => &mut m.parse_mode,
539        Document(m) => &mut m.parse_mode,
540    };
541
542    visitor(parse_mode);
543}