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
118
119
120
121
122
123
124
125
126
#[cfg(test)]
mod test;

use crate::internal::buffer_decode::{BufferDecode, BufferDecodeState};
use crate::internal::buffer_write::{BufferWrite, BufferWriteState};
use crate::internal::dec_helpers::request_head_parse;
use crate::internal::enc_helpers::header_encode;
use crate::internal::io_future::{IoFutureState, IoFutureWithOutputState};
use futures::{AsyncRead, AsyncWrite};
use http::request::Parts;
use http::{HeaderMap, Method, Request, Uri, Version};
use std::borrow::Cow;
use std::io;

#[derive(Clone, Debug)]
pub struct RequestHead<'a> {
    method: Method,
    uri: Cow<'a, Uri>,
    version: Version,
    headers: Cow<'a, HeaderMap>,
}

impl<'a> RequestHead<'a> {
    pub fn ref_parts(parts: &'a Parts) -> Self {
        Self {
            method: parts.method.clone(),
            uri: Cow::Borrowed(&parts.uri),
            version: parts.version,
            headers: Cow::Borrowed(&parts.headers),
        }
    }
    pub fn ref_request<B>(request: &'a Request<B>) -> Self {
        Self {
            method: request.method().clone(),
            uri: Cow::Borrowed(&request.uri()),
            version: request.version(),
            headers: Cow::Borrowed(&request.headers()),
        }
    }
    pub fn to_owned(self) -> RequestHead<'static> {
        RequestHead {
            method: self.method,
            uri: Cow::Owned(self.uri.into_owned()),
            version: self.version,
            headers: Cow::Owned(self.headers.into_owned()),
        }
    }
    pub fn to_vec(&self) -> io::Result<Vec<u8>> {
        use std::io::Write;
        let mut buffer = Vec::with_capacity(8192);
        writeln!(buffer, "{} {} {:?}\r", self.method, &self.uri, self.version)?;
        header_encode(&mut buffer, &self.headers)?;
        Ok(buffer)
    }
    pub fn encode<IO: AsyncWrite + Unpin>(&self, io: IO) -> BufferWrite<IO> {
        self.encode_state().into_future(io)
    }
    pub fn encode_state(&self) -> BufferWriteState {
        BufferWriteState::new(self.to_vec())
    }
    pub fn decode<IO: AsyncRead + Unpin>(io: IO) -> BufferDecode<IO, Self> {
        Self::decode_state().into_future(io)
    }
    pub fn decode_state() -> BufferDecodeState<Self> {
        BufferDecodeState::new(8192, 128, &request_head_parse)
    }
    pub fn method(&self) -> Method {
        self.method.clone()
    }
    pub fn uri(&self) -> &Uri {
        self.uri.as_ref()
    }
    pub fn version(&self) -> Version {
        self.version
    }
    pub fn headers(&self) -> &HeaderMap {
        self.headers.as_ref()
    }
    pub fn method_mut(&mut self) -> &mut Method {
        &mut self.method
    }
    pub fn uri_mut(&mut self) -> &mut Uri {
        self.uri.to_mut()
    }
    pub fn version_mut(&mut self) -> &mut Version {
        &mut self.version
    }
    pub fn headers_mut(&mut self) -> &mut HeaderMap {
        self.headers.to_mut()
    }
}

impl From<Parts> for RequestHead<'static> {
    fn from(parts: Parts) -> Self {
        Self {
            method: parts.method.clone(),
            uri: Cow::Owned(parts.uri),
            version: parts.version,
            headers: Cow::Owned(parts.headers),
        }
    }
}

impl<'a> From<RequestHead<'a>> for Parts {
    fn from(head: RequestHead<'a>) -> Self {
        let mut parts = Request::new(()).into_parts().0;
        parts.method = head.method;
        parts.uri = head.uri.into_owned();
        parts.version = head.version;
        parts.headers = head.headers.into_owned();
        parts
    }
}

impl<B> From<Request<B>> for RequestHead<'static> {
    fn from(request: Request<B>) -> Self {
        request.into_parts().0.into()
    }
}

impl<'a> From<RequestHead<'a>> for Request<()> {
    fn from(head: RequestHead<'a>) -> Self {
        let parts: Parts = head.into();
        Request::from_parts(parts, ())
    }
}