supabase_storage/build/
builder.rs

1use super::executor::Executor;
2use reqwest::{
3    header::{HeaderMap, HeaderValue, IntoHeaderName},
4    Body, Client, Error, Method, RequestBuilder, Response,
5};
6
7use url::Url;
8
9#[derive(Debug)]
10pub enum BodyType {
11    StringBody(String),
12    ReqwestBody(Body),
13}
14
15pub struct Builder {
16    pub url: Url,
17    pub headers: HeaderMap,
18    pub client: Client,
19    pub method: Method,
20    pub body: Option<BodyType>,
21}
22
23impl Builder {
24    /// Creates a new `Builder` instance.
25    ///
26    /// # Arguments
27    ///
28    /// * `url` - The URL for the request.
29    /// * `headers` - The `HeaderMap` containing the headers for the request.
30    /// * `client` - The `Client` to use for making the request.
31    ///
32    /// # Example
33    /// ```
34    /// use supabase_storage::build::builder::Builder;
35    /// use reqwest::header::{HeaderMap, HeaderValue};
36    /// use reqwest::Client;
37    /// use url::Url;
38    ///
39    /// let url = Url::parse("http://localhost").unwrap();
40    /// let builder = Builder::new(url, HeaderMap::new(), Client::new());
41    /// ```
42    pub fn new(url: Url, headers: HeaderMap, client: Client) -> Self {
43        Self {
44            url,
45            headers,
46            client,
47            method: Method::GET,
48            body: None,
49        }
50    }
51
52    /// Constructs and returns a `RequestBuilder` instance based on the current `Builder` configuration.
53    ///
54    /// # Returns
55    ///
56    /// * `RequestBuilder` - The constructed `RequestBuilder` instance.
57    // pub fn build(self) -> RequestBuilder {
58    //     self.client
59    //         .request(self.method, self.url)
60    //         .headers(self.headers)
61    //         .body(self.body.unwrap_or_default())
62    // }
63    pub fn build(self) -> RequestBuilder {
64        let mut request = self
65            .client
66            .request(self.method, self.url.to_string())
67            .headers(self.headers);
68
69        if let Some(body) = self.body {
70            match body {
71                BodyType::StringBody(body_string) => request = request.body(body_string),
72                BodyType::ReqwestBody(reqwest_body) => request = request.body(reqwest_body),
73            }
74        }
75
76        request
77    }
78
79    /// Adds a new header to the request.
80    ///
81    /// # Arguments
82    ///
83    /// * `key` - The header name, implementors of `IntoHeaderName` are accepted.
84    /// * `value` - The header value as a string.
85    ///
86    /// # Returns
87    ///
88    /// * `Self` - The updated `Builder` instance with the new header added.
89    ///
90    /// # Example
91    ///
92    /// ```
93    /// use supabase_storage::build::builder::Builder;
94    /// use reqwest::header::{HeaderMap, HeaderValue};
95    /// use reqwest::Client;
96    /// use url::Url;
97    ///
98    /// let url = Url::parse("http://localhost").unwrap();
99    ///
100    /// let _ = Builder::new(url, HeaderMap::new(), Client::new())
101    ///     .header("Authorization", HeaderValue::from_static("Bearer <token>"));
102    /// ```
103    pub fn header(mut self, key: impl IntoHeaderName, value: HeaderValue) -> Self {
104        self.headers.insert(key, value);
105        self
106    }
107
108    /// Executes the constructed HTTP request and returns the response as a `Result`.
109    ///
110    /// # Returns
111    ///
112    /// * `Result<Response, Error>` - The result of the executed request.
113    ///
114    /// # Example
115    ///
116    /// ```
117    /// use supabase_storage::build::builder::Builder;
118    /// use reqwest::header::{HeaderMap, HeaderValue};
119    /// use reqwest::Client;
120    /// use url::Url;
121    ///
122    /// #[tokio::main]
123    /// async fn main() {
124    ///     let url = Url::parse("http://localhost").unwrap();
125    ///     let mut headers = HeaderMap::new();
126    ///     headers.insert("Authorization", HeaderValue::from_static("Bearer YOUR_ACCESS_TOKEN"));
127    ///
128    ///     let builder = Builder::new(url, headers, Client::new())
129    ///         .header("Authorization", HeaderValue::from_static("Bearer <token>"));
130    ///
131    ///     // Execute the request and handle the response
132    ///     let response = builder.run().await;
133    ///     match response {
134    ///         Ok(response) => {
135    ///             let body = response.text().await.unwrap();
136    ///             println!("Response body: {:?}", body);
137    ///         }
138    ///         Err(error) => {
139    ///             eprintln!("Error occurred: {:?}", error);
140    ///         }
141    ///     }
142    /// }
143    /// ```
144    pub async fn run(self) -> Result<Response, Error> {
145        self.build().send().await
146    }
147
148    /// Creates a new `Executor` instance based on the current `Builder` configuration.
149    ///
150    /// # Returns
151    ///
152    /// * `Executor` - The created `Executor` instance.
153    pub fn create_executor(self) -> Executor {
154        Executor::new(self)
155    }
156}
157
158#[cfg(test)]
159mod test {
160    use reqwest::{
161        header::{HeaderMap, HeaderValue},
162        Client,
163    };
164    use url::Url;
165
166    use super::Builder;
167
168    #[test]
169    fn test_create_builder() {
170        let mut headers = HeaderMap::new();
171        headers.insert("Authorization", HeaderValue::from_static("Bearer test"));
172        let url = Url::parse("http://localhost").unwrap();
173        let builder = Builder::new(url, headers, Client::new());
174        assert_eq!(builder.url.scheme(), "http");
175        assert_eq!(builder.headers.len(), 1);
176    }
177
178    #[test]
179    fn test_add_header() {
180        let url = Url::parse("http://localhost").unwrap();
181        let builder = Builder::new(url, HeaderMap::new(), Client::new())
182            .header("Authorization", HeaderValue::from_static("Bearer test"));
183        assert_eq!(builder.headers.len(), 1);
184    }
185}