diff --git a/CHANGELOG.md b/CHANGELOG.md index 54ad8b18..45f82d13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,10 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [unreleased] +### Added + +- `HasPayload`, `Request` and `Requester` implementations for `either::Either` ([#103][pr103]) + +[pr103]: https://github.com/teloxide/teloxide-core/pull/103 + ## 0.3.1 - 2021-07-07 - Minor documentation tweaks ([#102][pr102]) -- Remove `Self: 'static` buound on `RequesterExt::throttle` ([#102][pr102]) +- Remove `Self: 'static` bound on `RequesterExt::throttle` ([#102][pr102]) [pr102]: https://github.com/teloxide/teloxide-core/pull/102 diff --git a/Cargo.toml b/Cargo.toml index 80019fea..ba9ee45d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ thiserror = "1.0.20" once_cell = "1.5.0" never = "0.1.0" chrono = "0.4.19" +either = "1.6.1" vecrem = { version = "0.1", optional = true } @@ -75,7 +76,10 @@ cache_me = [] # AutoSend bot adaptor auto_send = [] -full = ["throttle", "cache_me", "auto_send"] +# Erased bot adaptor +erased = [] + +full = ["throttle", "cache_me", "auto_send", "erased"] [package.metadata.docs.rs] all-features = true diff --git a/src/requests/has_payload.rs b/src/requests/has_payload.rs index de6bd333..870bc50c 100644 --- a/src/requests/has_payload.rs +++ b/src/requests/has_payload.rs @@ -1,3 +1,5 @@ +use either::Either; + use crate::requests::Payload; /// Represents types having payload inside. @@ -42,3 +44,19 @@ where self } } + +impl HasPayload for Either +where + L: HasPayload, + R: HasPayload, +{ + type Payload = L::Payload; + + fn payload_mut(&mut self) -> &mut Self::Payload { + self.as_mut().either(<_>::payload_mut, <_>::payload_mut) + } + + fn payload_ref(&self) -> &Self::Payload { + self.as_ref().either(<_>::payload_ref, <_>::payload_ref) + } +} diff --git a/src/requests/request.rs b/src/requests/request.rs index e2f06b64..aed2490e 100644 --- a/src/requests/request.rs +++ b/src/requests/request.rs @@ -1,5 +1,8 @@ use std::future::Future; +use either::Either; +use futures::future; + use crate::requests::{HasPayload, Output}; /// A ready-to-send Telegram request. @@ -85,3 +88,28 @@ pub trait Request: HasPayload { /// ``` fn send_ref(&self) -> Self::SendRef; } + +impl Request for Either +where + L: Request, + R: Request, +{ + type Err = L::Err; + + type Send = future::Either; + + type SendRef = future::Either; + + fn send(self) -> Self::Send { + self.map_left(<_>::send) + .map_right(<_>::send) + .either(future::Either::Left, future::Either::Right) + } + + fn send_ref(&self) -> Self::SendRef { + self.as_ref() + .map_left(<_>::send_ref) + .map_right(<_>::send_ref) + .either(future::Either::Left, future::Either::Right) + } +} diff --git a/src/requests/requester.rs b/src/requests/requester.rs index 2338072d..47337b51 100644 --- a/src/requests/requester.rs +++ b/src/requests/requester.rs @@ -915,3 +915,52 @@ where forward_all! {} } + +macro_rules! fty_either { + ($T:ident) => { + either::Either + }; +} + +macro_rules! fwd_either { + ($m:ident $this:ident ($($arg:ident : $T:ty),*)) => { + match ($this) { + either::Either::Left(l) => either::Either::Left(l.$m($($arg),*)), + either::Either::Right(r) => either::Either::Right(r.$m($($arg),*)), + } + }; +} + +impl Requester for either::Either +where + LR: Requester, + RR: Requester, +{ + type Err = LR::Err; + + requester_forward! { + get_me, log_out, close, get_updates, set_webhook, delete_webhook, get_webhook_info, + forward_message, copy_message, send_message, send_photo, send_audio, send_document, + send_video, send_animation, send_voice, send_video_note, send_media_group, send_location, + edit_message_live_location, edit_message_live_location_inline, + stop_message_live_location, stop_message_live_location_inline, send_venue, + send_contact, send_poll, send_dice, send_chat_action, get_user_profile_photos, + get_file, kick_chat_member, ban_chat_member, unban_chat_member, restrict_chat_member, + promote_chat_member, set_chat_administrator_custom_title, set_chat_permissions, + export_chat_invite_link, create_chat_invite_link, edit_chat_invite_link, + revoke_chat_invite_link, set_chat_photo, delete_chat_photo, set_chat_title, + set_chat_description, pin_chat_message, unpin_chat_message, unpin_all_chat_messages, + leave_chat, get_chat, get_chat_administrators, get_chat_members_count, get_chat_member_count, get_chat_member, + set_chat_sticker_set, delete_chat_sticker_set, answer_callback_query, + set_my_commands, get_my_commands, delete_my_commands, answer_inline_query, edit_message_text, + edit_message_text_inline, edit_message_caption, edit_message_caption_inline, + edit_message_media, edit_message_media_inline, edit_message_reply_markup, + edit_message_reply_markup_inline, stop_poll, delete_message, send_sticker, + get_sticker_set, upload_sticker_file, create_new_sticker_set, + add_sticker_to_set, set_sticker_position_in_set, delete_sticker_from_set, + set_sticker_set_thumb, send_invoice, answer_shipping_query, + answer_pre_checkout_query, set_passport_data_errors, send_game, + set_game_score, set_game_score_inline, get_game_high_scores, + get_updates_fault_tolerant => fwd_either, fty_either + } +}