1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
use std::future::{Future, IntoFuture};
// use either::Either;
// use futures::future;
use crate::requests::{HasPayload, Output};
/// A ready-to-send Telegram request.
// FIXME(waffle): Write better doc for the trait
///
/// ## Implementation notes
///
/// It is not recommended to do any kind of _work_ in `send` or `send_ref`.
/// Instead it's recommended to do all the (possible) stuff in the returned
/// future. In other words — keep it lazy.
///
/// This is crucial for request wrappers which may want to cancel and/or never
/// send the underlying request. E.g.: [`Throttle<B>`]'s `send_ref` calls
/// `B::send_ref` while _not_ meaning to really send the request at the moment.
///
/// [`Throttle<B>`]: crate::adaptors::Throttle
#[cfg_attr(all(any(docsrs, dep_docsrs), feature = "nightly"), doc(notable_trait))]
pub trait Request
where
Self: HasPayload,
Self: IntoFuture<Output = Result<Output<Self>, Self::Err>, IntoFuture = Self::Send>,
{
/// The type of an error that may happen while sending a request to
/// Telegram.
type Err: std::error::Error + Send;
/// The type of the future returned by the [`send`](Request::send) method.
type Send: Future<Output = Result<Output<Self>, Self::Err>> + Send;
/// A type of the future returned by the [`send_ref`](Request::send_ref)
/// method.
// Note: it intentionally forbids borrowing from `self` though we couldn't allow
// borrowing without GATs anyway.
type SendRef: Future<Output = Result<Output<Self>, Self::Err>> + Send;
/// Send this request.
///
/// ## Examples
///
/// ```
/// # async {
/// use teloxide_core::{
/// payloads::GetMe,
/// requests::{JsonRequest, Request},
/// types::Me,
/// Bot,
/// };
///
/// let bot = Bot::new("TOKEN");
///
/// // Note: it's recommended to `Requester` instead of creating requests directly
/// let method = GetMe::new();
/// let request = JsonRequest::new(bot, method);
/// let request_clone = request.clone();
/// let _: Me = request.send().await.unwrap();
///
/// // You can also just await requests, without calling `send`:
/// let _: Me = request_clone.await.unwrap();
/// # };
/// ```
#[must_use = "Futures are lazy and do nothing unless polled or awaited"]
fn send(self) -> Self::Send;
/// Send this request by reference.
///
/// This method is analogous to [`send`](Request::send), but it doesn't take
/// the ownership of `self`. This allows to send the same (or slightly
/// different) requests over and over.
///
/// Also, it is expected that calling this method is better than just
/// cloning requests. (Because instead of copying all the data
/// and then serializing it, this method should just serialize the data.)
///
/// ## Examples
///
/// ```
/// # async {
/// use teloxide_core::{prelude::*, requests::Request, types::ChatId, Bot};
///
/// let bot = Bot::new("TOKEN");
/// # let chat_ids = vec![1i64, 2, 3, 4].into_iter().map(ChatId).map(Into::into).collect::<Vec<_>>();
///
/// let mut req = bot.send_message(ChatId(0xAAAAAAAA), "Hi there!");
/// for chat_id in chat_ids {
/// req.chat_id = chat_id;
/// req.send_ref().await.unwrap();
/// }
/// # };
/// ```
#[must_use = "Futures are lazy and do nothing unless polled or awaited"]
fn send_ref(&self) -> Self::SendRef;
#[cfg(feature = "erased")]
fn erase<'a>(self) -> crate::adaptors::erased::ErasedRequest<'a, Self::Payload, Self::Err>
where
Self: Sized + 'a,
{
crate::adaptors::erased::ErasedRequest::erase(self)
}
}
// FIXME: re-introduce `Either` impls once `Either: IntoFuture` (or make out own
// `Either`) (same for `Requester`)
// impl<L, R> Request for Either<L, R>
// where
// L: Request,
// R: Request<Payload = L::Payload, Err = L::Err>,
// {
// type Err = L::Err;
// type Send = future::Either<L::Send, R::Send>;
// type SendRef = future::Either<L::SendRef, R::SendRef>;
// 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)
// }
// }