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}