teloxide_core/requests/
multipart.rs

1use std::future::IntoFuture;
2
3use serde::{de::DeserializeOwned, Serialize};
4
5use crate::{
6    bot::Bot,
7    requests::{HasPayload, MultipartPayload, Payload, Request, ResponseResult},
8    RequestError,
9};
10
11/// A ready-to-send Telegram request whose payload is sent using
12/// [multipart/form-data].
13///
14/// [multipart/form-data]: https://core.telegram.org/bots/api#making-requests
15#[must_use = "Requests are lazy and do nothing unless sent"]
16#[derive(Clone)]
17pub struct MultipartRequest<P> {
18    bot: Bot,
19    payload: P,
20}
21
22impl<P> MultipartRequest<P> {
23    pub const fn new(bot: Bot, payload: P) -> Self {
24        Self { bot, payload }
25    }
26}
27
28impl<P> Request for MultipartRequest<P>
29where
30    // FIXME(waffle):
31    //   this is required on stable because of
32    //   https://github.com/rust-lang/rust/issues/76882
33    //   when it's resolved or `type_alias_impl_trait` feature
34    //   stabilized, we should remove 'static restriction
35    //
36    // (though critically, currently we have no
37    // non-'static payloads)
38    P: 'static,
39    P: Payload + MultipartPayload + Serialize,
40    P::Output: DeserializeOwned,
41{
42    type Err = RequestError;
43    type Send = Send<P>;
44    type SendRef = SendRef<P>;
45
46    fn send(self) -> Self::Send {
47        Send::new(self)
48    }
49
50    fn send_ref(&self) -> Self::SendRef {
51        SendRef::new(self)
52    }
53}
54
55impl<P> IntoFuture for MultipartRequest<P>
56where
57    P: 'static,
58    P: Payload + MultipartPayload + Serialize,
59    P::Output: DeserializeOwned,
60{
61    type Output = Result<P::Output, RequestError>;
62    type IntoFuture = <Self as Request>::Send;
63
64    fn into_future(self) -> Self::IntoFuture {
65        self.send()
66    }
67}
68
69impl<P> HasPayload for MultipartRequest<P>
70where
71    P: Payload,
72{
73    type Payload = P;
74
75    fn payload_mut(&mut self) -> &mut Self::Payload {
76        &mut self.payload
77    }
78
79    fn payload_ref(&self) -> &Self::Payload {
80        &self.payload
81    }
82}
83
84impl<P> core::ops::Deref for MultipartRequest<P>
85where
86    P: 'static,
87    P: Payload + MultipartPayload,
88    P::Output: DeserializeOwned,
89{
90    type Target = P;
91
92    fn deref(&self) -> &Self::Target {
93        self.payload_ref()
94    }
95}
96
97impl<P> core::ops::DerefMut for MultipartRequest<P>
98where
99    P: 'static,
100    P: Payload + MultipartPayload,
101    P::Output: DeserializeOwned,
102{
103    fn deref_mut(&mut self) -> &mut Self::Target {
104        self.payload_mut()
105    }
106}
107
108req_future! {
109    def: |it: MultipartRequest<U>| {
110        it.bot.execute_multipart(&mut {it.payload})
111    }
112    pub Send<U> (inner0) -> ResponseResult<U::Output>
113    where
114        U: 'static,
115        U: Payload + MultipartPayload + Serialize,
116        U::Output: DeserializeOwned,
117}
118
119req_future! {
120    def: |it: &MultipartRequest<U>| {
121        it.bot.execute_multipart_ref(&it.payload)
122    }
123    pub SendRef<U> (inner1) -> ResponseResult<U::Output>
124    where
125        U: 'static,
126        U: Payload + MultipartPayload + Serialize,
127        U::Output: DeserializeOwned,
128}