http1_spec/
response_head_renderer.rs

1use std::io::{Error as IoError, ErrorKind as IoErrorKind};
2
3use http::{response::Parts, Response, Version};
4
5use crate::{
6    head_renderer::HeadRenderer, ReasonPhrase, COLON, CRLF, HTTP_VERSION_10, HTTP_VERSION_11,
7    HTTP_VERSION_2, HTTP_VERSION_3, SP,
8};
9
10#[derive(Default)]
11pub struct ResponseHeadRenderer {}
12
13impl HeadRenderer<(Response<()>, ReasonPhrase)> for ResponseHeadRenderer {
14    fn new() -> Self {
15        Self::default()
16    }
17
18    fn render(&self, head: (Response<()>, ReasonPhrase), buf: &mut Vec<u8>) -> Result<(), IoError> {
19        let (head, reason_phrase) = head;
20
21        let (parts, _) = head.into_parts();
22        HeadRenderer::<(Parts, ReasonPhrase)>::render(self, (parts, reason_phrase), buf)
23    }
24}
25
26impl HeadRenderer<(Parts, ReasonPhrase)> for ResponseHeadRenderer {
27    fn new() -> Self {
28        Self::default()
29    }
30
31    fn render(&self, head: (Parts, ReasonPhrase), buf: &mut Vec<u8>) -> Result<(), IoError> {
32        let (parts, reason_phrase) = head;
33
34        let version_bytes = match parts.version {
35            Version::HTTP_10 => HTTP_VERSION_10,
36            Version::HTTP_11 => HTTP_VERSION_11,
37            Version::HTTP_2 => HTTP_VERSION_2,
38            Version::HTTP_3 => HTTP_VERSION_3,
39            _ => return Err(IoError::new(IoErrorKind::InvalidInput, "unimplemented")),
40        };
41
42        buf.extend_from_slice(version_bytes);
43        buf.extend_from_slice(&[SP]);
44        buf.extend_from_slice(parts.status.as_str().as_bytes());
45        buf.extend_from_slice(&[SP]);
46        if let Some(reason_phrase) = reason_phrase.or_else(|| {
47            parts
48                .status
49                .canonical_reason()
50                .map(|x| x.as_bytes().to_vec())
51        }) {
52            buf.extend_from_slice(&reason_phrase[..]);
53        }
54        buf.extend_from_slice(CRLF);
55
56        for (k, v) in &parts.headers {
57            buf.extend_from_slice(k.to_string().as_bytes());
58            buf.extend_from_slice(&[COLON]);
59            buf.extend_from_slice(v.as_bytes());
60            buf.extend_from_slice(CRLF);
61        }
62
63        buf.extend_from_slice(CRLF);
64
65        Ok(())
66    }
67}