1use core::marker::PhantomData;
2use std::{collections::HashMap, io::BufReader};
3
4use crate::{HttpMethod, HttpRequest, stream};
5
6pub struct Url;
7pub struct NoUrl;
8
9pub struct HttpRequestBuilder<U> {
10 method: HttpMethod,
11 url: Option<Box<str>>,
12 headers: HashMap<Box<str>, Box<str>>,
13 response_headers: HashMap<Box<str>, Box<str>>,
14 params: HashMap<Box<str>, Box<str>>,
15 version: f32,
16 status: u16,
17 body: Option<Box<[u8]>>,
18 _pd: PhantomData<U>,
19}
20
21impl<U> HttpRequestBuilder<U> {
22 pub fn method(mut self, m: HttpMethod) -> Self {
23 self.method = m;
24 self
25 }
26
27 pub fn header(mut self, k: impl Into<Box<str>>, v: impl Into<Box<str>>) -> Self {
28 self.headers.insert(k.into(), v.into());
29 self
30 }
31
32 pub fn response_header(mut self, k: impl Into<Box<str>>, v: impl Into<Box<str>>) -> Self {
33 self.response_headers.insert(k.into(), v.into());
34 self
35 }
36
37 pub fn param(mut self, k: impl Into<Box<str>>, v: impl Into<Box<str>>) -> Self {
38 self.params.insert(k.into(), v.into());
39 self
40 }
41
42 pub fn version(mut self, v: f32) -> Self {
43 self.version = v;
44 self
45 }
46
47 pub fn status(mut self, code: u16) -> Self {
48 self.status = code;
49 self
50 }
51
52 pub fn body(mut self, body: impl Into<Box<[u8]>>) -> Self {
53 self.body = Some(body.into());
54 self
55 }
56}
57
58impl HttpRequestBuilder<Url> {
59 pub fn build(self) -> HttpRequest {
60 HttpRequest {
61 body: self.body,
62 status: self.status,
63 params: self.params,
64 headers: self.headers,
65 method: self.method,
66 url: self.url.unwrap(),
67 stream: BufReader::new(stream::dummy()),
68 version: self.version,
69 response_headers: self.response_headers,
70 }
71 }
72}
73
74impl HttpRequestBuilder<NoUrl> {
75 pub fn new() -> Self {
76 Self {
77 method: HttpMethod::GET,
78 url: None,
79 response_headers: HashMap::new(),
80 headers: HashMap::new(),
81 params: HashMap::new(),
82 status: 200,
83 body: None,
84 version: 1.0,
85 _pd: PhantomData,
86 }
87 }
88
89 pub fn url(self, url: impl Into<Box<str>>) -> HttpRequestBuilder<Url> {
90 HttpRequestBuilder {
91 url: Some(url.into()),
92 body: self.body,
93 status: self.status,
94 params: self.params,
95 headers: self.headers,
96 version: self.version,
97 response_headers: self.response_headers,
98 method: self.method,
99 _pd: PhantomData,
100 }
101 }
102}
103
104impl Default for HttpRequestBuilder<NoUrl> {
105 fn default() -> Self {
106 Self::new()
107 }
108}