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