1use std::collections::HashMap;
2
3#[derive(Debug, Clone, Default)]
7pub struct RequestOption {
8 pub(crate) tenant_key: Option<String>,
9 pub(crate) user_access_token: Option<String>,
10 pub(crate) app_access_token: Option<String>,
11 pub(crate) tenant_access_token: Option<String>,
12 pub(crate) need_helpdesk_auth: bool,
13 pub(crate) request_id: Option<String>,
14 pub(crate) app_ticket: Option<String>,
15 pub(crate) file_upload: bool,
16 pub(crate) file_download: bool,
17 pub(crate) header: HashMap<String, String>,
18}
19
20impl RequestOption {
21 pub fn builder() -> RequestOptionBuilder {
23 RequestOptionBuilder::default()
24 }
25}
26
27#[derive(Default)]
31pub struct RequestOptionBuilder {
32 option: RequestOption,
33}
34
35impl RequestOptionBuilder {
36 pub fn tenant_key(mut self, tenant_key: impl ToString) -> Self {
38 self.option.tenant_key = Some(tenant_key.to_string());
39 self
40 }
41
42 pub fn user_access_token(mut self, user_access_token: impl ToString) -> Self {
44 self.option.user_access_token = Some(user_access_token.to_string());
45 self
46 }
47
48 pub fn app_access_token(mut self, app_access_token: impl ToString) -> Self {
50 self.option.app_access_token = Some(app_access_token.to_string());
51 self
52 }
53
54 pub fn tenant_access_token(mut self, tenant_access_token: impl ToString) -> Self {
56 self.option.tenant_access_token = Some(tenant_access_token.to_string());
57 self
58 }
59
60 pub fn need_helpdesk_auth(mut self, need_helpdesk_auth: bool) -> Self {
62 self.option.need_helpdesk_auth = need_helpdesk_auth;
63 self
64 }
65
66 pub fn request_id(mut self, request_id: impl ToString) -> Self {
68 self.option.request_id = Some(request_id.to_string());
69 self
70 }
71
72 pub fn app_ticket(mut self, app_ticket: impl ToString) -> Self {
74 self.option.app_ticket = Some(app_ticket.to_string());
75 self
76 }
77
78 pub fn file_upload(mut self, file_upload: bool) -> Self {
80 self.option.file_upload = file_upload;
81 self
82 }
83
84 pub fn file_download(mut self, file_download: bool) -> Self {
86 self.option.file_download = file_download;
87 self
88 }
89
90 pub fn header(mut self, header: HashMap<String, String>) -> Self {
92 self.option.header = header;
93 self
94 }
95
96 pub fn add_header(mut self, key: impl ToString, value: impl ToString) -> Self {
98 self.option
99 .header
100 .insert(key.to_string(), value.to_string());
101 self
102 }
103
104 pub fn build(self) -> RequestOption {
106 self.option
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113 use std::collections::HashMap;
114
115 #[test]
116 fn test_request_option_default() {
117 let option = RequestOption::default();
118 assert_eq!(option.tenant_key, None);
119 assert_eq!(option.user_access_token, None);
120 assert_eq!(option.app_access_token, None);
121 assert_eq!(option.tenant_access_token, None);
122 assert!(!option.need_helpdesk_auth);
123 assert_eq!(option.request_id, None);
124 assert_eq!(option.app_ticket, None);
125 assert!(!option.file_upload);
126 assert!(!option.file_download);
127 assert!(option.header.is_empty());
128 }
129
130 #[test]
131 fn test_request_option_builder_creation() {
132 let builder = RequestOption::builder();
133 let option = builder.build();
134
135 assert_eq!(option.tenant_key, None);
137 assert_eq!(option.user_access_token, None);
138 assert_eq!(option.app_access_token, None);
139 assert_eq!(option.tenant_access_token, None);
140 assert!(!option.need_helpdesk_auth);
141 assert_eq!(option.request_id, None);
142 assert_eq!(option.app_ticket, None);
143 assert!(!option.file_upload);
144 assert!(!option.file_download);
145 assert!(option.header.is_empty());
146 }
147
148 #[test]
149 fn test_request_option_builder_tenant_key() {
150 let option = RequestOption::builder().tenant_key("test_tenant").build();
151
152 assert_eq!(option.tenant_key, Some("test_tenant".to_string()));
153
154 let option = RequestOption::builder()
156 .tenant_key("another_tenant".to_string())
157 .build();
158
159 assert_eq!(option.tenant_key, Some("another_tenant".to_string()));
160 }
161
162 #[test]
163 fn test_request_option_builder_user_access_token() {
164 let option = RequestOption::builder()
165 .user_access_token("user_token_123")
166 .build();
167
168 assert_eq!(option.user_access_token, Some("user_token_123".to_string()));
169
170 let option = RequestOption::builder()
172 .user_access_token("user_token_456".to_string())
173 .build();
174
175 assert_eq!(option.user_access_token, Some("user_token_456".to_string()));
176 }
177
178 #[test]
179 fn test_request_option_builder_app_access_token() {
180 let option = RequestOption::builder()
181 .app_access_token("app_token_789")
182 .build();
183
184 assert_eq!(option.app_access_token, Some("app_token_789".to_string()));
185
186 let option = RequestOption::builder()
188 .app_access_token("app_token_012".to_string())
189 .build();
190
191 assert_eq!(option.app_access_token, Some("app_token_012".to_string()));
192 }
193
194 #[test]
195 fn test_request_option_builder_tenant_access_token() {
196 let option = RequestOption::builder()
197 .tenant_access_token("tenant_token_345")
198 .build();
199
200 assert_eq!(
201 option.tenant_access_token,
202 Some("tenant_token_345".to_string())
203 );
204
205 let option = RequestOption::builder()
207 .tenant_access_token("tenant_token_678".to_string())
208 .build();
209
210 assert_eq!(
211 option.tenant_access_token,
212 Some("tenant_token_678".to_string())
213 );
214 }
215
216 #[test]
217 fn test_request_option_builder_need_helpdesk_auth() {
218 let option = RequestOption::builder().need_helpdesk_auth(true).build();
219
220 assert!(option.need_helpdesk_auth);
221
222 let option = RequestOption::builder().need_helpdesk_auth(false).build();
223
224 assert!(!option.need_helpdesk_auth);
225 }
226
227 #[test]
228 fn test_request_option_builder_request_id() {
229 let option = RequestOption::builder().request_id("req_12345").build();
230
231 assert_eq!(option.request_id, Some("req_12345".to_string()));
232
233 let option = RequestOption::builder()
235 .request_id("req_67890".to_string())
236 .build();
237
238 assert_eq!(option.request_id, Some("req_67890".to_string()));
239 }
240
241 #[test]
242 fn test_request_option_builder_app_ticket() {
243 let option = RequestOption::builder().app_ticket("ticket_abc").build();
244
245 assert_eq!(option.app_ticket, Some("ticket_abc".to_string()));
246
247 let option = RequestOption::builder()
249 .app_ticket("ticket_def".to_string())
250 .build();
251
252 assert_eq!(option.app_ticket, Some("ticket_def".to_string()));
253 }
254
255 #[test]
256 fn test_request_option_builder_file_upload() {
257 let option = RequestOption::builder().file_upload(true).build();
258
259 assert!(option.file_upload);
260
261 let option = RequestOption::builder().file_upload(false).build();
262
263 assert!(!option.file_upload);
264 }
265
266 #[test]
267 fn test_request_option_builder_file_download() {
268 let option = RequestOption::builder().file_download(true).build();
269
270 assert!(option.file_download);
271
272 let option = RequestOption::builder().file_download(false).build();
273
274 assert!(!option.file_download);
275 }
276
277 #[test]
278 fn test_request_option_builder_header() {
279 let mut headers = HashMap::new();
280 headers.insert("Content-Type".to_string(), "application/json".to_string());
281 headers.insert("Authorization".to_string(), "Bearer token".to_string());
282
283 let option = RequestOption::builder().header(headers.clone()).build();
284
285 assert_eq!(option.header.len(), 2);
286 assert_eq!(
287 option.header.get("Content-Type"),
288 Some(&"application/json".to_string())
289 );
290 assert_eq!(
291 option.header.get("Authorization"),
292 Some(&"Bearer token".to_string())
293 );
294 }
295
296 #[test]
297 fn test_request_option_builder_add_header() {
298 let option = RequestOption::builder()
299 .add_header("X-Custom-Header", "custom_value")
300 .add_header("X-Another-Header", "another_value")
301 .build();
302
303 assert_eq!(option.header.len(), 2);
304 assert_eq!(
305 option.header.get("X-Custom-Header"),
306 Some(&"custom_value".to_string())
307 );
308 assert_eq!(
309 option.header.get("X-Another-Header"),
310 Some(&"another_value".to_string())
311 );
312
313 let option = RequestOption::builder()
315 .add_header("X-String-Header".to_string(), "string_value".to_string())
316 .build();
317
318 assert_eq!(option.header.len(), 1);
319 assert_eq!(
320 option.header.get("X-String-Header"),
321 Some(&"string_value".to_string())
322 );
323 }
324
325 #[test]
326 fn test_request_option_builder_add_header_multiple() {
327 let option = RequestOption::builder()
328 .add_header("Header1", "value1")
329 .add_header("Header2", "value2")
330 .add_header("Header3", "value3")
331 .build();
332
333 assert_eq!(option.header.len(), 3);
334 assert_eq!(option.header.get("Header1"), Some(&"value1".to_string()));
335 assert_eq!(option.header.get("Header2"), Some(&"value2".to_string()));
336 assert_eq!(option.header.get("Header3"), Some(&"value3".to_string()));
337 }
338
339 #[test]
340 fn test_request_option_builder_header_and_add_header() {
341 let mut initial_headers = HashMap::new();
342 initial_headers.insert("Initial-Header".to_string(), "initial_value".to_string());
343
344 let option = RequestOption::builder()
345 .header(initial_headers)
346 .add_header("Added-Header", "added_value")
347 .build();
348
349 assert_eq!(option.header.len(), 2);
350 assert_eq!(
351 option.header.get("Initial-Header"),
352 Some(&"initial_value".to_string())
353 );
354 assert_eq!(
355 option.header.get("Added-Header"),
356 Some(&"added_value".to_string())
357 );
358 }
359
360 #[test]
361 fn test_request_option_builder_chaining() {
362 let option = RequestOption::builder()
363 .tenant_key("test_tenant")
364 .user_access_token("user_token")
365 .app_access_token("app_token")
366 .tenant_access_token("tenant_token")
367 .need_helpdesk_auth(true)
368 .request_id("req_123")
369 .app_ticket("ticket_456")
370 .file_upload(true)
371 .file_download(false)
372 .add_header("X-Test", "test_value")
373 .build();
374
375 assert_eq!(option.tenant_key, Some("test_tenant".to_string()));
376 assert_eq!(option.user_access_token, Some("user_token".to_string()));
377 assert_eq!(option.app_access_token, Some("app_token".to_string()));
378 assert_eq!(option.tenant_access_token, Some("tenant_token".to_string()));
379 assert!(option.need_helpdesk_auth);
380 assert_eq!(option.request_id, Some("req_123".to_string()));
381 assert_eq!(option.app_ticket, Some("ticket_456".to_string()));
382 assert!(option.file_upload);
383 assert!(!option.file_download);
384 assert_eq!(option.header.len(), 1);
385 assert_eq!(option.header.get("X-Test"), Some(&"test_value".to_string()));
386 }
387
388 #[test]
389 fn test_request_option_builder_empty_strings() {
390 let option = RequestOption::builder()
391 .tenant_key("")
392 .user_access_token("")
393 .app_access_token("")
394 .tenant_access_token("")
395 .request_id("")
396 .app_ticket("")
397 .build();
398
399 assert_eq!(option.tenant_key, Some("".to_string()));
400 assert_eq!(option.user_access_token, Some("".to_string()));
401 assert_eq!(option.app_access_token, Some("".to_string()));
402 assert_eq!(option.tenant_access_token, Some("".to_string()));
403 assert_eq!(option.request_id, Some("".to_string()));
404 assert_eq!(option.app_ticket, Some("".to_string()));
405 }
406
407 #[test]
408 fn test_request_option_builder_special_characters() {
409 let option = RequestOption::builder()
410 .tenant_key("tenant@#$%^&*()")
411 .user_access_token("token_with_symbols!@#")
412 .request_id("req_with_unicode_测试")
413 .add_header("X-Special-Chars", "value@#$%")
414 .build();
415
416 assert_eq!(option.tenant_key, Some("tenant@#$%^&*()".to_string()));
417 assert_eq!(
418 option.user_access_token,
419 Some("token_with_symbols!@#".to_string())
420 );
421 assert_eq!(option.request_id, Some("req_with_unicode_测试".to_string()));
422 assert_eq!(
423 option.header.get("X-Special-Chars"),
424 Some(&"value@#$%".to_string())
425 );
426 }
427
428 #[test]
429 fn test_request_option_builder_overwrite_header() {
430 let mut initial_headers = HashMap::new();
431 initial_headers.insert("Test-Header".to_string(), "initial_value".to_string());
432
433 let option = RequestOption::builder()
434 .header(initial_headers)
435 .add_header("Test-Header", "overwritten_value")
436 .build();
437
438 assert_eq!(option.header.len(), 1);
439 assert_eq!(
440 option.header.get("Test-Header"),
441 Some(&"overwritten_value".to_string())
442 );
443 }
444
445 #[test]
446 fn test_request_option_builder_empty_header_map() {
447 let empty_headers = HashMap::new();
448
449 let option = RequestOption::builder().header(empty_headers).build();
450
451 assert!(option.header.is_empty());
452 }
453
454 #[test]
455 fn test_request_option_debug_clone() {
456 let option = RequestOption::builder()
457 .tenant_key("test")
458 .need_helpdesk_auth(true)
459 .build();
460
461 let debug_str = format!("{:?}", option);
463 assert!(debug_str.contains("RequestOption"));
464
465 let cloned_option = option.clone();
467 assert_eq!(option.tenant_key, cloned_option.tenant_key);
468 assert_eq!(option.need_helpdesk_auth, cloned_option.need_helpdesk_auth);
469 }
470
471 #[test]
472 fn test_request_option_builder_default() {
473 let builder = RequestOptionBuilder::default();
474 let option = builder.build();
475
476 let default_option = RequestOption::default();
478
479 assert_eq!(option.tenant_key, default_option.tenant_key);
480 assert_eq!(option.user_access_token, default_option.user_access_token);
481 assert_eq!(option.app_access_token, default_option.app_access_token);
482 assert_eq!(
483 option.tenant_access_token,
484 default_option.tenant_access_token
485 );
486 assert_eq!(option.need_helpdesk_auth, default_option.need_helpdesk_auth);
487 assert_eq!(option.request_id, default_option.request_id);
488 assert_eq!(option.app_ticket, default_option.app_ticket);
489 assert_eq!(option.file_upload, default_option.file_upload);
490 assert_eq!(option.file_download, default_option.file_download);
491 assert_eq!(option.header.len(), default_option.header.len());
492 }
493}