Skip to main content

teloxide_core_ng/requests/
request.rs

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