1use serde::de::DeserializeOwned;
2use reqwest::{Client, RequestBuilder};
3use std::fmt::{Debug, Formatter, Result as FmtResult};
4use std::ops::{Deref, DerefMut};
5use std::marker::PhantomData;
6use crate::error::{HttpError, Result};
7use crate::options::*;
8
9pub struct Request<'a, T> {
15 client: &'a Client,
16 token: &'a Option<String>,
17 endpoint: String,
18 options: Options,
19 marker: PhantomData<T>
20}
21
22impl<'a, T: DeserializeOwned> Request<'a, T> {
23 pub(crate) fn new(client: &'a Client, token: &'a Option<String>, endpoint: impl ToString) -> Self {
24 let mut this = Self {
25 client,
26 token,
27 endpoint: endpoint.to_string(),
28 options: Default::default(),
29 marker: PhantomData
30 };
31
32 this.question_number(10);
33 this
34 }
35
36 pub fn into_owned(self) -> OwnedRequest<T> {
59 OwnedRequest {
60 client: self.client.clone(),
61 token: self.token.clone(),
62 endpoint: self.endpoint,
63 options: self.options,
64 marker: PhantomData
65 }
66 }
67
68 pub(crate) fn prepare(&mut self, mut request: RequestBuilder) -> RequestBuilder {
69 if let Some(t) = self.token {
70 request = request.query(&[("token", t)]);
71 }
72 self.options.prepare(request)
73 }
74
75 pub async fn send(mut self) -> Result<T> {
98 Self::make_request(self.prepare(self.client.get(&self.endpoint))).await
99 }
100
101 async fn make_request(req: RequestBuilder) -> Result<T>
102 where
103 {
104 let response = req.send().await?;
105
106 match response.status().as_u16() {
107 200 => Ok(response.json().await?),
108 c if c >= 500 => Err(HttpError::InternalServerError(response.text().await?)),
109 _ => Err(HttpError::UnsuccessfulRequest(response.status(), response.text().await?)),
110 }
111 }
112}
113
114impl<T> Deref for Request<'_, T> {
115 type Target = Options;
116
117 fn deref(&self) -> &Self::Target {
118 &self.options
119 }
120}
121
122impl<T> DerefMut for Request<'_, T> {
123 fn deref_mut(&mut self) -> &mut Self::Target {
124 &mut self.options
125 }
126}
127
128impl<T: DeserializeOwned> Debug for Request<'_, T> {
129 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
130 f.debug_struct("Request")
131 .field("token", &self.token)
132 .field("endpoint", &self.endpoint)
133 .field("options", &self.options)
134 .finish()
135 }
136}
137
138pub struct OwnedRequest<T> {
143 client: Client,
144 token: Option<String>,
145 endpoint: String,
146 options: Options,
147 marker: PhantomData<T>
148}
149
150unsafe impl<T: DeserializeOwned> Send for OwnedRequest<T> {}
151
152impl<T: DeserializeOwned> OwnedRequest<T> {
153 pub(crate) fn prepare(&mut self, mut request: RequestBuilder) -> RequestBuilder {
154 if let Some(t) = &self.token {
155 request = request.query(&[("token", t)]);
156 }
157 self.options.prepare(request)
158 }
159
160 pub async fn send(mut self) -> Result<T> {
184 Request::make_request(self.prepare(self.client.get(&self.endpoint))).await
185 }
186}
187
188impl<T: DeserializeOwned> Deref for OwnedRequest<T> {
189 type Target = Options;
190
191 fn deref(&self) -> &Self::Target {
192 &self.options
193 }
194}
195
196impl<T: DeserializeOwned> DerefMut for OwnedRequest<T> {
197 fn deref_mut(&mut self) -> &mut Self::Target {
198 &mut self.options
199 }
200}
201
202impl<T: DeserializeOwned> Debug for OwnedRequest<T> {
203 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
204 f.debug_struct("OwnedRequest")
205 .field("token", &self.token)
206 .field("endpoint", &self.endpoint)
207 .field("options", &self.options)
208 .finish()
209 }
210}