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// }