Skip to main content

neptunium_http/
request.rs

1use std::collections::HashMap;
2
3use bon::Builder;
4use reqwest::{
5    Error, Method, Response,
6    header::{HeaderMap, HeaderValue},
7};
8
9use crate::client::HttpClient;
10#[cfg(feature = "user_api")]
11use crate::client::TokenType;
12
13#[derive(Clone, Debug, Builder)]
14pub struct Request {
15    pub body: Option<String>,
16    pub headers: Option<HeaderMap<HeaderValue>>,
17    pub method: Method,
18    pub path: String,
19    #[builder(default = true)]
20    pub use_authorization_token: bool,
21    pub params: Option<HashMap<String, String>>,
22}
23
24impl Request {
25    /// Execute the request. For a non-consuming version, see [`Self::borrowed_execute`].
26    /// # Errors
27    /// Returns an error if there was an error while sending the request, a redirect loop was detected or the redirect limit was exhausted.
28    pub async fn execute(self, client: &HttpClient) -> Result<Response, Error> {
29        let mut request = client
30            .reqwest_client
31            .request(self.method, format!("{}{}", client.api_base_url, self.path))
32            .header("User-Agent", &client.user_agent);
33        if let Some(headers) = self.headers {
34            request = request.headers(headers);
35        }
36        if self.use_authorization_token {
37            #[cfg(not(feature = "user_api"))]
38            let token = format!("Bot {}", *client.token);
39            #[cfg(feature = "user_api")]
40            let token = match client.token_type {
41                TokenType::Bot => format!("Bot {}", *client.token),
42                TokenType::User => (*client.token).clone(),
43            };
44
45            request = request.header("Authorization", token);
46        }
47        if let Some(body) = self.body {
48            request = request.body(body);
49        }
50        if let Some(params) = self.params {
51            request = request.query(&params);
52        }
53
54        request.send().await
55    }
56
57    /// Execute the request without consuming it. This clones certain fields when necessary. For a consuming version, see [`Self::execute`].
58    /// # Errors
59    /// Returns the same errors as [`Self::execute`].
60    pub async fn borrowed_execute(&self, client: &HttpClient) -> Result<Response, Error> {
61        let mut request = client
62            .reqwest_client
63            .request(
64                self.method.clone(),
65                format!("{}{}", client.api_base_url, self.path),
66            )
67            .header("User-Agent", &client.user_agent);
68        if let Some(headers) = &self.headers {
69            request = request.headers(headers.clone());
70        }
71        if self.use_authorization_token {
72            request = request.header("Authorization", format!("Bot {}", *client.token));
73        }
74        if let Some(body) = &self.body {
75            request = request.body(body.clone());
76        }
77
78        request.send().await
79    }
80}