asknothingx2_util/api/
header_mut.rs

1use http::{
2    header::{
3        ACCEPT, ACCEPT_ENCODING, ACCEPT_LANGUAGE, ACCESS_CONTROL_ALLOW_HEADERS,
4        ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN, AUTHORIZATION, CACHE_CONTROL,
5        CONNECTION, CONTENT_LENGTH, CONTENT_TYPE, ORIGIN, REFERER, USER_AGENT,
6    },
7    HeaderMap, HeaderName, HeaderValue,
8};
9
10use crate::api::{
11    content_type::{Application, Multipart, Text},
12    AuthScheme,
13};
14
15use super::request::HeaderError;
16
17pub mod headers {
18    use http::HeaderName;
19
20    pub const CLIENT_ID: HeaderName = HeaderName::from_static("client-id");
21    pub const X_API_KEY: HeaderName = HeaderName::from_static("x-api-key");
22    pub const X_REQUEST_ID: HeaderName = HeaderName::from_static("x-request-id");
23}
24
25pub struct HeaderMut<'a> {
26    header: &'a mut HeaderMap,
27}
28
29impl<'a> HeaderMut<'a> {
30    pub fn new(header: &'a mut HeaderMap) -> Self {
31        Self { header }
32    }
33
34    pub fn header(&mut self, key: HeaderName, value: HeaderValue) -> &mut Self {
35        self.header.insert(key, value);
36        self
37    }
38
39    pub fn header_static(&mut self, key: HeaderName, value: &'static str) -> &mut Self {
40        self.header.insert(key, HeaderValue::from_static(value));
41        self
42    }
43
44    pub fn header_str(&mut self, key: HeaderName, value: &str) -> Result<&mut Self, HeaderError> {
45        let val = HeaderValue::from_str(value).map_err(|e| HeaderError::InvalidHeaderValue {
46            name: key.to_string(),
47            value: value.to_string(),
48            reason: e.to_string(),
49        })?;
50
51        self.header.insert(key, val);
52        Ok(self)
53    }
54
55    pub fn append(
56        &mut self,
57        key: HeaderName,
58        value: HeaderValue,
59    ) -> Result<&mut Self, http::Error> {
60        self.header.append(key, value);
61
62        Ok(self)
63    }
64
65    pub fn extend(&mut self, headers: HeaderMap) -> &mut Self {
66        self.header.extend(headers);
67
68        self
69    }
70
71    pub fn is_empty(&self) -> bool {
72        self.header.is_empty()
73    }
74
75    /// Client-Id: <id>
76    pub fn client_id(&mut self, id: &str) -> Result<&mut Self, HeaderError> {
77        self.header_str(headers::CLIENT_ID, id)
78    }
79
80    /// User-Agent: <agent>
81    pub fn user_agent(&mut self, agent: &str) -> Result<&mut Self, HeaderError> {
82        self.header_str(USER_AGENT, agent)
83    }
84
85    /// Cache-Control: no-cache
86    pub fn cache_control_no_cache(&mut self) -> &mut Self {
87        self.header
88            .insert(CACHE_CONTROL, HeaderValue::from_static("no-cache"));
89        self
90    }
91
92    /// Cache-Control: <value>
93    pub fn cache_control(&mut self, value: &str) -> Result<&mut Self, HeaderError> {
94        self.header_str(CACHE_CONTROL, value)
95    }
96
97    /// X-API-Key: <key>
98    pub fn api_key(&mut self, key: &str) -> Result<&mut Self, HeaderError> {
99        self.header_str(headers::X_API_KEY, key)
100    }
101
102    /// X-Request-ID: <id>
103    pub fn request_id(&mut self, id: &str) -> Result<&mut Self, HeaderError> {
104        self.header_str(headers::X_REQUEST_ID, id)
105    }
106
107    /// Origin: <origin>
108    pub fn origin(&mut self, origin: &str) -> Result<&mut Self, HeaderError> {
109        self.header_str(ORIGIN, origin)
110    }
111
112    /// Referer: <referer>
113    pub fn referer(&mut self, referer: &str) -> Result<&mut Self, HeaderError> {
114        self.header_str(REFERER, referer)
115    }
116
117    // CORS headers
118    /// Access-Control-Allow-Origin: *
119    pub fn cors_allow_all(&mut self) -> &mut Self {
120        self.header
121            .insert(ACCESS_CONTROL_ALLOW_ORIGIN, HeaderValue::from_static("*"));
122        self
123    }
124
125    /// Access-Control-Allow-Origin: <origin>
126    pub fn cors_allow_origin(&mut self, origin: &str) -> Result<&mut Self, HeaderError> {
127        self.header_str(ACCESS_CONTROL_ALLOW_ORIGIN, origin)
128    }
129
130    /// Access-Control-Allow-Methods: GET, POST, PUT, DELETE
131    pub fn cors_allow_methods_standard(&mut self) -> &mut Self {
132        self.header.insert(
133            ACCESS_CONTROL_ALLOW_METHODS,
134            HeaderValue::from_static("GET,POST,PUT,DELETE"),
135        );
136        self
137    }
138
139    /// Access-Control-Allow-Headers: Content-Type, Authorization
140    pub fn cors_allow_headers_standard(&mut self) -> &mut Self {
141        self.header.insert(
142            ACCESS_CONTROL_ALLOW_HEADERS,
143            HeaderValue::from_static("Content-Type,Authorization"),
144        );
145        self
146    }
147
148    /// Connection: keep-alive
149    pub fn connection_keep_alive(&mut self) -> &mut Self {
150        self.header
151            .insert(CONNECTION, HeaderValue::from_static("keep-alive"));
152        self
153    }
154
155    /// Connection: close
156    pub fn connection_close(&mut self) -> &mut Self {
157        self.header
158            .insert(CONNECTION, HeaderValue::from_static("close"));
159        self
160    }
161
162    /// Content-Length: <length>
163    pub fn content_length(&mut self, length: u64) -> &mut Self {
164        self.header.insert(
165            CONTENT_LENGTH,
166            HeaderValue::from_str(&length.to_string()).unwrap(),
167        );
168        self
169    }
170
171    /// Accept: application/json, Content-Type: application/json
172    pub fn json_api(&mut self) -> &mut Self {
173        self.accept_json().content_type_json()
174    }
175
176    // pub fn build(self) -> HeaderMap {
177    //     self.header
178    // }
179}
180
181impl<'a> HeaderMut<'a> {
182    /// ACCEPT: application/json
183    pub fn accept_json(&mut self) -> &mut Self {
184        self.header
185            .insert(ACCEPT, Application::Json.to_header_value());
186        self
187    }
188
189    /// ACCEPT: text/html
190    pub fn accept_html(&mut self) -> &mut Self {
191        self.header.insert(ACCEPT, Text::Html.to_header_value());
192        self
193    }
194
195    /// ACCEPT: text/plain
196    pub fn accept_text(&mut self) -> &mut Self {
197        self.header
198            .insert(ACCEPT, HeaderValue::from_static("text/plain"));
199        self
200    }
201
202    /// ACCEPT: */*
203    pub fn accept_any(&mut self) -> &mut Self {
204        self.header.insert(ACCEPT, HeaderValue::from_static("*/*"));
205        self
206    }
207
208    /// ACCEPT: multi items
209    pub fn accept_mulity(&mut self, items: &[&str]) -> Result<&mut Self, HeaderError> {
210        self.header_str(ACCEPT, &items.join(","))
211    }
212
213    /// Accept-Encoding: gzip, deflate, br
214    pub fn accept_encoding_standard(&mut self) -> &mut Self {
215        self.header
216            .insert(ACCEPT_ENCODING, HeaderValue::from_static("gzip,deflate,br"));
217        self
218    }
219
220    /// Accept-Language: en-US, en;q=0.9
221    pub fn accept_language_en(&mut self) -> &mut Self {
222        self.header
223            .insert(ACCEPT_LANGUAGE, HeaderValue::from_static("en-US,en;q=0.9"));
224        self
225    }
226
227    /// Accept-Language: <lang>
228    pub fn accept_language(&mut self, lang: &str) -> Result<&mut Self, HeaderError> {
229        self.header_str(ACCEPT_LANGUAGE, lang)
230    }
231}
232
233impl<'a> HeaderMut<'a> {
234    /// CONTENT-TYPE: application/x-www-form-urlencoded
235    pub fn content_type_formencoded(&mut self) -> &mut Self {
236        self.header
237            .insert(CONTENT_TYPE, Application::FormUrlEncoded.to_header_value());
238        self
239    }
240
241    /// CONTENT-TYPE: application/json
242    pub fn content_type_json(&mut self) -> &mut Self {
243        self.header
244            .insert(CONTENT_TYPE, Application::Json.to_header_value());
245        self
246    }
247
248    /// CONTENT-TYPE: text/plain
249    pub fn content_type_text(&mut self) -> &mut Self {
250        self.header
251            .insert(CONTENT_TYPE, Text::Plain.to_header_value());
252        self
253    }
254
255    /// CONTENT-TYPE: text/html
256    pub fn content_type_html(&mut self) -> &mut Self {
257        self.header
258            .insert(CONTENT_TYPE, Text::Html.to_header_value());
259        self
260    }
261
262    /// CONTENT-TYPE: multipart/form-data
263    pub fn content_type_multipart(&mut self) -> &mut Self {
264        self.header
265            .insert(CONTENT_TYPE, Multipart::FormData.to_header_value());
266        self
267    }
268}
269
270impl<'a> HeaderMut<'a> {
271    /// Authorization: <type> <credentials>
272    pub fn authorization(&mut self, auth: AuthScheme) -> &mut Self {
273        self.header
274            .insert(AUTHORIZATION, auth.to_header_value().unwrap());
275        self
276    }
277
278    pub fn basic_auth(&mut self, username: &str, password: &str) -> &mut Self {
279        self.authorization(AuthScheme::basic(username, password))
280    }
281
282    pub fn bearer_token(&mut self, token: &str) -> &mut Self {
283        self.authorization(AuthScheme::bearer(token))
284    }
285}