1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use crate::{
HttpError, Header, RequestHeader, ResponseHeader,
data::{
Data,
encodings::{ Ascii, HeaderFieldKey, Uri }
}
};
use std::{ collections::HashMap, convert::TryFrom };
pub struct RequestBuilder {
method: Option<Data<Ascii>>,
uri: Option<Data<Uri>>,
version: Option<Data<Ascii>>,
header_fields: HashMap<Data<HeaderFieldKey>, Data<Ascii>>
}
impl RequestBuilder {
pub fn new() -> Self {
Self{ method: None, uri: None, version: None, header_fields: HashMap::new() }
}
pub fn method(mut self, method: Data<Ascii>) -> Self {
self.method = Some(method);
self
}
pub fn uri(mut self, uri: Data<Uri>) -> Self {
self.uri = Some(uri);
self
}
pub fn version(mut self, version: Data<Ascii>) -> Self {
self.version = Some(version);
self
}
pub fn field(mut self, key: Data<HeaderFieldKey>, value: Data<Ascii>) -> Self {
self.header_fields.insert(key, value);
self
}
pub fn build(self) -> Result<RequestHeader, HttpError> {
let method = self.method.ok_or(HttpError::ApiMisuse)?;
let uri = self.uri.ok_or(HttpError::ApiMisuse)?;
let version = self.version.ok_or(HttpError::ApiMisuse)?;
let uri_ascii: Data<Ascii> = Data::try_from(&uri as &[u8])?;
Ok(RequestHeader {
header: Header {
status_line: (method, uri_ascii, version),
fields: self.header_fields
}, uri
})
}
}
pub struct ResponseBuilder {
version: Option<Data<Ascii>>,
status: Option<u16>,
reason: Option<Data<Ascii>>,
header_fields: HashMap<Data<HeaderFieldKey>, Data<Ascii>>
}
impl ResponseBuilder {
pub fn new() -> Self {
Self{ version: None, status: None, reason: None, header_fields: HashMap::new() }
}
pub fn version(mut self, version: Data<Ascii>) -> Self {
self.version = Some(version);
self
}
pub fn status(mut self, status: u16) -> Self {
self.status = Some(status);
self
}
pub fn reason(mut self, info: Data<Ascii>) -> Self {
self.reason = Some(info);
self
}
pub fn field(mut self, key: Data<HeaderFieldKey>, value: Data<Ascii>) -> Self {
self.header_fields.insert(key, value);
self
}
pub fn build(self) -> Result<ResponseHeader, HttpError> {
let version = self.version.ok_or(HttpError::ApiMisuse)?;
let status = self.status.ok_or(HttpError::ApiMisuse)?;
let reason = self.reason.ok_or(HttpError::ApiMisuse)?;
let status_ascii: Data<Ascii> = Data::try_from(status.to_string().into_bytes())
.expect("Should never fail because all number literals are a subset of ASCII");
Ok(ResponseHeader {
header: Header {
status_line: (version, status_ascii, reason),
fields: self.header_fields
}, status
})
}
}