Skip to content

Commit ea65b56

Browse files
committed
feat: added TryFrom<BytesMut> for MessageHead struct
1 parent d695321 commit ea65b56

File tree

6 files changed

+83
-63
lines changed

6 files changed

+83
-63
lines changed

header-plz/src/body_headers/parse.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ mod tests {
5858
User-Agent: curl/7.29.0\r\n\
5959
Connection: keep-alive\r\n\r\n";
6060
let buf = BytesMut::from(request);
61-
let result = MessageHead::<Request>::new(buf).unwrap();
61+
let result = MessageHead::<Request>::try_from(buf).unwrap();
6262
let body_headers = result.parse_body_headers();
6363
assert!(body_headers.is_none());
6464
}
@@ -72,7 +72,7 @@ mod tests {
7272
User-Agent: curl/7.29.0\r\n\
7373
Connection: keep-alive\r\n\r\n";
7474
let buf = BytesMut::from(request);
75-
let result = MessageHead::<Request>::new(buf).unwrap();
75+
let result = MessageHead::<Request>::try_from(buf).unwrap();
7676
let body_headers = result.parse_body_headers();
7777
assert!(body_headers.is_none());
7878
}
@@ -84,7 +84,7 @@ mod tests {
8484
Content-Type: application/json\r\n\
8585
\r\n";
8686
let buf = BytesMut::from(request);
87-
let result = MessageHead::<Request>::new(buf).unwrap();
87+
let result = MessageHead::<Request>::try_from(buf).unwrap();
8888
match result.parse_body_headers() {
8989
Some(body_headers) => {
9090
assert!(body_headers.content_type.is_some());
@@ -106,7 +106,7 @@ mod tests {
106106
Content-Encoding: gzip\r\n\
107107
Transfer-Encoding: chunked\r\n\r\n";
108108
let buf = BytesMut::from(request);
109-
let result = MessageHead::<Request>::new(buf).unwrap();
109+
let result = MessageHead::<Request>::try_from(buf).unwrap();
110110
match result.parse_body_headers() {
111111
Some(body_headers) => {
112112
assert_eq!(body_headers.content_type.unwrap(), ContentType::Application);
@@ -130,7 +130,7 @@ mod tests {
130130
Content-Type: text/plain\r\n\
131131
Content-Length: 12\r\n\r\n";
132132
let buf = BytesMut::from(response);
133-
let result = MessageHead::<Response>::new(buf).unwrap();
133+
let result = MessageHead::<Response>::try_from(buf).unwrap();
134134
let body_headers = result.parse_body_headers();
135135
if let Some(body_headers) = body_headers {
136136
assert!(body_headers.content_encoding.is_none());
@@ -151,7 +151,7 @@ mod tests {
151151
Host: localhost\r\n\
152152
Content-Type: text/plain\r\n\r\n";
153153
let buf = BytesMut::from(response);
154-
let result = MessageHead::<Response>::new(buf).unwrap();
154+
let result = MessageHead::<Response>::try_from(buf).unwrap();
155155
let body_headers = result.parse_body_headers();
156156
if let Some(body_headers) = body_headers {
157157
assert!(body_headers.content_encoding.is_none());
@@ -170,7 +170,7 @@ mod tests {
170170
Content-Length: 0\r\n\
171171
Content-Type: text/plain\r\n\r\n";
172172
let buf = BytesMut::from(response);
173-
let result = MessageHead::<Response>::new(buf).unwrap();
173+
let result = MessageHead::<Response>::try_from(buf).unwrap();
174174
let body_headers = result.parse_body_headers();
175175
assert!(body_headers.is_none());
176176
}

header-plz/src/info_line/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use error::*;
66

77
// Trait for parsing info line of request and response.
88
pub trait InfoLine {
9-
fn build_infoline(raw: BytesMut) -> Result<Self, InfoLineError>
9+
fn try_build_infoline(raw: BytesMut) -> Result<Self, InfoLineError>
1010
where
1111
Self: Sized;
1212

header-plz/src/info_line/request.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub struct Request {
2828
*/
2929

3030
impl InfoLine for Request {
31-
fn build_infoline(mut data: BytesMut) -> Result<Request, InfoLineError> {
31+
fn try_build_infoline(mut data: BytesMut) -> Result<Request, InfoLineError> {
3232
let mut index =
3333
data.iter()
3434
.position(|&x| x == OWS as u8)
@@ -96,7 +96,7 @@ mod tests {
9696
let buf = BytesMut::from(req);
9797
let verify = buf[0..20].to_owned();
9898
let verify_ptr = buf[0..20].as_ptr_range();
99-
let request = Request::build_infoline(buf).unwrap();
99+
let request = Request::try_build_infoline(buf).unwrap();
100100
assert_eq!(request.method(), b"GET");
101101
assert_eq!(request.uri_as_string(), "/echo");
102102
assert_eq!(request.version, " HTTP/1.1\r\n");
@@ -111,7 +111,7 @@ mod tests {
111111
let buf = BytesMut::from(req);
112112
let verify_ptr = buf[..37].as_ptr_range();
113113
let verify = buf.clone();
114-
match Request::build_infoline(buf) {
114+
match Request::try_build_infoline(buf) {
115115
Ok(info_line) => {
116116
assert_eq!(info_line.method, "CONNECT ");
117117
assert_eq!(info_line.uri, "www.google.com:443");
@@ -132,7 +132,7 @@ mod tests {
132132
let buf = BytesMut::from(req);
133133
let verify_ptr = buf[..].as_ptr_range();
134134
let verify = buf.clone();
135-
match Request::build_infoline(buf) {
135+
match Request::try_build_infoline(buf) {
136136
Ok(info_line) => {
137137
assert_eq!(info_line.method, "GET ");
138138
assert_eq!(info_line.uri, "http://www.google.com/");
@@ -153,7 +153,7 @@ mod tests {
153153
let buf = BytesMut::from(req);
154154
let verify_ptr = buf[..].as_ptr_range();
155155
let verify = buf.clone();
156-
match Request::build_infoline(buf) {
156+
match Request::try_build_infoline(buf) {
157157
Ok(info_line) => {
158158
assert_eq!(info_line.method, "GET ");
159159
assert_eq!(info_line.uri, "http://www.google.com:8080/");
@@ -172,7 +172,7 @@ mod tests {
172172
fn test_return_queries() -> Result<(), Box<dyn Error>> {
173173
let req = "GET /users?param=value&param2=value2 HTTP/1.1\r\n\r\n";
174174
let buf = BytesMut::from(req);
175-
let info_line = Request::build_infoline(buf)?;
175+
let info_line = Request::try_build_infoline(buf)?;
176176
let uri = info_line.uri()?;
177177
let query = uri.query().unwrap();
178178
assert_eq!("param=value&param2=value2", query);

header-plz/src/info_line/response.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub struct Response {
1818
*/
1919

2020
impl InfoLine for Response {
21-
fn build_infoline(mut data: BytesMut) -> Result<Response, InfoLineError> {
21+
fn try_build_infoline(mut data: BytesMut) -> Result<Response, InfoLineError> {
2222
// "1" in decimal
2323
let index = if data[5] == 49 {
2424
9
@@ -73,7 +73,7 @@ mod tests {
7373
let buf = BytesMut::from(response);
7474
let verify = buf.clone();
7575
let initial_ptr = buf.as_ptr_range();
76-
let response = Response::build_infoline(buf).unwrap();
76+
let response = Response::try_build_infoline(buf).unwrap();
7777
assert_eq!(response.version, "HTTP/1.1 ");
7878
assert_eq!(response.status, "200");
7979
assert_eq!(response.reason, " OK\r\n");
@@ -88,7 +88,7 @@ mod tests {
8888
let buf = BytesMut::from(response);
8989
let verify = buf.clone();
9090
let initial_ptr = buf.as_ptr_range();
91-
let response = Response::build_infoline(buf).unwrap();
91+
let response = Response::try_build_infoline(buf).unwrap();
9292
assert_eq!(response.version, "HTTP/2 ");
9393
assert_eq!(response.status, "200");
9494
assert_eq!(response.reason, " OK\r\n");

header-plz/src/message_head/mod.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
use crate::{header_map::HeaderMap, info_line::InfoLine};
2+
use bytes::BytesMut;
3+
mod try_from_bytes;
4+
5+
// Represent the Header region Infoline + HeaderMap.
6+
#[cfg_attr(any(test, debug_assertions), derive(Debug, PartialEq, Eq))]
7+
pub struct MessageHead<T> {
8+
info_line: T,
9+
header_map: HeaderMap,
10+
}
11+
12+
impl<T> MessageHead<T>
13+
where
14+
T: InfoLine,
15+
{
16+
pub fn new(info_line: T, header_map: HeaderMap) -> Self {
17+
MessageHead {
18+
info_line,
19+
header_map,
20+
}
21+
}
22+
23+
// Convert into Data
24+
pub fn into_data(self) -> BytesMut {
25+
let mut data = self.info_line.into_data();
26+
data.unsplit(self.header_map.into_data());
27+
data
28+
}
29+
30+
pub fn header_map(&self) -> &HeaderMap {
31+
&self.header_map
32+
}
33+
34+
pub fn infoline(&self) -> &T {
35+
&self.info_line
36+
}
37+
38+
pub fn infoline_as_mut(&mut self) -> &mut T {
39+
&mut self.info_line
40+
}
41+
42+
pub fn header_map_as_mut(&mut self) -> &mut HeaderMap {
43+
&mut self.header_map
44+
}
45+
}

header-plz/src/message_head.rs renamed to header-plz/src/message_head/try_from_bytes.rs

Lines changed: 21 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,29 @@
1-
use crate::{error::HeaderReadError, header_map::HeaderMap, info_line::InfoLine};
21
use bytes::BytesMut;
32

4-
#[cfg_attr(any(test, debug_assertions), derive(Debug, PartialEq, Eq))]
5-
pub struct MessageHead<T> {
6-
info_line: T,
7-
header_map: HeaderMap,
8-
}
3+
use crate::{error::HeaderReadError, header_map::HeaderMap, info_line::InfoLine};
4+
5+
use super::MessageHead;
96

10-
// Represent the Header region Infoline + HeaderMap.
11-
impl<T> MessageHead<T>
7+
/* Steps:
8+
* 1. Find CR in buf.
9+
* 2. Split buf at CR_index + 2 (CRLF)
10+
* 3. Build Infoline
11+
*
12+
* Error:
13+
* HttpReadError::InfoLine [3]
14+
* HttpReadError::HeaderStruct [Default]
15+
*/
16+
17+
impl<T> TryFrom<BytesMut> for MessageHead<T>
1218
where
1319
T: InfoLine,
1420
{
15-
/* Steps:
16-
* 1. Find CR in buf.
17-
* 2. Split buf at CR_index + 2 (CRLF)
18-
* 3. Build Infoline
19-
*
20-
* Error:
21-
* HttpReadError::InfoLine [3]
22-
* HttpReadError::HeaderStruct [Default]
23-
*/
21+
type Error = HeaderReadError;
2422

25-
pub fn new(mut data: BytesMut) -> Result<Self, HeaderReadError> {
23+
fn try_from(mut data: BytesMut) -> Result<Self, HeaderReadError> {
2624
if let Some(infoline_index) = data.iter().position(|&x| x == 13) {
2725
let raw = data.split_to(infoline_index + 2);
28-
let info_line = T::build_infoline(raw)?;
26+
let info_line = T::try_build_infoline(raw)?;
2927
return Ok(Self {
3028
info_line,
3129
header_map: HeaderMap::from(data),
@@ -35,29 +33,6 @@ where
3533
String::from_utf8_lossy(&data).to_string(),
3634
))
3735
}
38-
39-
// Convert into Data
40-
pub fn into_data(self) -> BytesMut {
41-
let mut data = self.info_line.into_data();
42-
data.unsplit(self.header_map.into_data());
43-
data
44-
}
45-
46-
pub fn header_map(&self) -> &HeaderMap {
47-
&self.header_map
48-
}
49-
50-
pub fn infoline(&self) -> &T {
51-
&self.info_line
52-
}
53-
54-
pub fn infoline_as_mut(&mut self) -> &mut T {
55-
&mut self.info_line
56-
}
57-
58-
pub fn header_map_as_mut(&mut self) -> &mut HeaderMap {
59-
&mut self.header_map
60-
}
6136
}
6237

6338
#[cfg(test)]
@@ -68,7 +43,7 @@ mod tests {
6843
use super::*;
6944

7045
#[test]
71-
fn test_header_struct_build_request() {
46+
fn test_message_head_request_try_from() {
7247
let request = "GET / HTTP/1.1\r\n\
7348
Host: localhost\r\n\
7449
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n\
@@ -79,7 +54,7 @@ mod tests {
7954
";
8055
let buf = BytesMut::from(request);
8156
let org = buf.as_ptr_range();
82-
let result = MessageHead::<Request>::new(buf).unwrap();
57+
let result = MessageHead::<Request>::try_from(buf).unwrap();
8358
assert_eq!(result.info_line.method(), b"GET");
8459
assert_eq!(result.info_line.uri_as_string(), "/");
8560
let verify = result.into_data();
@@ -88,14 +63,14 @@ mod tests {
8863
}
8964

9065
#[test]
91-
fn test_header_struct_build_infoline_response() {
66+
fn test_message_head_response_try_from() {
9267
let response = "HTTP/1.1 200 OK\r\n\
9368
Host: localhost\r\n\
9469
Content-Type: text/plain\r\n\
9570
Content-Length: 12\r\n\r\n";
9671
let buf = BytesMut::from(response);
9772
let org = buf.as_ptr_range();
98-
let result = MessageHead::<Response>::new(buf).unwrap();
73+
let result = MessageHead::<Response>::try_from(buf).unwrap();
9974
assert_eq!(result.info_line.status(), b"200");
10075
let verify = result.into_data();
10176
assert_eq!(verify, response);

0 commit comments

Comments
 (0)