1use std::collections::BTreeMap;
2use std::net::TcpStream;
3use std::str::Lines;
4
5use crate::{ParseErrorKind, Request};
6use crate::error::HttpParseError;
7use crate::error::ParseErrorKind::Util;
8
9pub(crate) const KEY_VALUE_DELIMITER: &str = ": ";
10pub(crate) const NEW_LINE: char = '\n';
11pub(crate) const EMPTY_CHAR: char = ' ';
12pub(crate) const OPTION_WAS_EMPTY: &str = "the Option<?> was empty and couldn't get unwrapped";
13pub(crate) const INDEX_WAS_WRONG: &str = "The provided index didn't match";
14
15pub(crate) trait ParseKeyValue {
16 fn parse_key_value(&self) -> String;
17}
18
19impl ParseKeyValue for BTreeMap<String, String> {
20 fn parse_key_value(&self) -> String {
21 let mut string = String::new();
22 for (key, value) in self {
23 string.push_str(key);
24 string.push_str(KEY_VALUE_DELIMITER);
25 string.push_str(value);
26 string.push(NEW_LINE);
27 }
28 string
29 }
30}
31
32pub trait Destruct {
52 type Item;
55 fn destruct(self) -> Self::Item;
57}
58
59pub(crate) fn parse_body(lines: &mut Lines) -> String {
60 let mut string = String::new();
61 let mut first = true;
62 lines.for_each(|str| {
63 if !first {
64 string.push(NEW_LINE);
65 }
66 first = false;
67 string.push_str(str);
68 });
69 string
70}
71
72pub(crate) fn parse_header(lines: &mut Lines) -> Result<BTreeMap<String, String>, HttpParseError> {
73 let mut map: BTreeMap<String, String> = BTreeMap::new();
74 let mut opt_line = lines.next();
75 while opt_line.is_some() {
76 let line = opt_line.unwrap();
77 if !line.is_empty() {
78 let (key, val) = parse_key_value(line)?;
79 map.insert(key, val);
80 opt_line = lines.next();
81 } else {
82 opt_line = None
83 }
84 }
85 Ok(map)
86}
87
88pub(crate) fn parse_uri(str: Option<&str>) -> Result<String, HttpParseError> {
89 str.ok_or(error_option_empty(Util)).map(String::from)
90}
91
92fn parse_key_value(str: &str) -> Result<(String, String), HttpParseError> {
93 let mut key_value = str.split(KEY_VALUE_DELIMITER);
94 let key = key_value
95 .next()
96 .ok_or(error_option_empty(Util))
97 .map(String::from)?;
98 let value = key_value
99 .next()
100 .ok_or(error_option_empty(Util))
101 .map(String::from)?;
102 Ok((key, value))
103}
104
105pub(crate) fn error_option_empty(kind: ParseErrorKind) -> HttpParseError {
106 HttpParseError::from((kind, OPTION_WAS_EMPTY))
107}
108
109pub trait TryRequest {
111 fn try_to_request(&mut self) -> Result<Request, HttpParseError>;
113}
114
115impl TryRequest for TcpStream {
116 fn try_to_request(&mut self) -> Result<Request, HttpParseError> {
117 Request::try_from(self)
118 }
119}