http_protocol/response/
mod.rs

1use crate::status_code::get_reason_phrase_by_status_code;
2use crate::{Body, Headers, HttpVersion, ReasonPhrase, StatusCode};
3use bytes::{BufMut, Bytes};
4use std::error::Error;
5use std::fmt;
6
7#[derive(Debug)]
8pub enum ResponseBuilderError {
9    HttpVersionIsNone,
10    StatusCodeIsNone,
11    ReasonPhraseIsNone,
12    HeadersIsNone,
13    BodyIsNone,
14}
15
16impl fmt::Display for ResponseBuilderError {
17    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18        match self {
19            ResponseBuilderError::HttpVersionIsNone => write!(f, "HTTP version is None."),
20            ResponseBuilderError::StatusCodeIsNone => write!(f, "Status code is None."),
21            ResponseBuilderError::ReasonPhraseIsNone => write!(f, "Reason phrase is None."),
22            ResponseBuilderError::HeadersIsNone => write!(f, "Headers is None."),
23            ResponseBuilderError::BodyIsNone => write!(f, "Body is None."),
24        }
25    }
26}
27
28impl Error for ResponseBuilderError {}
29
30#[derive(Debug, Clone)]
31pub struct ResponseBuilder {
32    http_version: Option<HttpVersion>,
33    status_code: Option<StatusCode>,
34    reason_phrase: Option<ReasonPhrase>,
35    headers: Option<Headers>,
36    body: Option<Body>,
37}
38
39impl ResponseBuilder {
40    pub fn http_version(&mut self, http_version: HttpVersion) -> &mut Self {
41        self.http_version = Some(http_version);
42        self
43    }
44    pub fn status_code(&mut self, status_code: StatusCode) -> &mut Self {
45        if let Some(reason_phrase) = get_reason_phrase_by_status_code(&status_code) {
46            self.reason_phrase = Some(reason_phrase)
47        }
48        self.status_code = Some(status_code);
49        self
50    }
51    pub fn reason_phrase(&mut self, reason_phrase: ReasonPhrase) -> &mut Self {
52        self.reason_phrase = Some(reason_phrase);
53        self
54    }
55    pub fn headers(&mut self, headers: Headers) -> &mut Self {
56        self.headers = Some(headers);
57        self
58    }
59    pub fn body(&mut self, body: Body) -> &mut Self {
60        self.body = Some(body);
61        self
62    }
63    pub fn build(self) -> Result<Response, ResponseBuilderError> {
64        let http_version = self
65            .http_version
66            .ok_or(ResponseBuilderError::HttpVersionIsNone)?;
67        let status_code = self
68            .status_code
69            .ok_or(ResponseBuilderError::StatusCodeIsNone)?;
70        let reason_phrase = self
71            .reason_phrase
72            .ok_or(ResponseBuilderError::ReasonPhraseIsNone)?;
73        let headers = self.headers.ok_or(ResponseBuilderError::HeadersIsNone)?;
74        let body = self.body.ok_or(ResponseBuilderError::BodyIsNone)?;
75        Ok(Response {
76            http_version,
77            status_code,
78            reason_phrase,
79            headers,
80            body,
81        })
82    }
83}
84
85#[derive(Debug, Clone)]
86pub struct Response {
87    http_version: HttpVersion,
88    status_code: StatusCode,
89    reason_phrase: ReasonPhrase,
90    headers: Headers,
91    body: Body,
92}
93
94impl Response {
95    pub fn builder() -> ResponseBuilder {
96        ResponseBuilder {
97            http_version: None,
98            status_code: None,
99            reason_phrase: None,
100            headers: None,
101            body: None,
102        }
103    }
104}
105
106impl From<Response> for Bytes {
107    fn from(r: Response) -> Self {
108        let mut buf = Vec::<u8>::new();
109        buf.put(Bytes::from(r.http_version));
110        buf.put(Bytes::from_static(&[sp!()]));
111        buf.put(Bytes::from(r.status_code));
112        buf.put(Bytes::from_static(&[sp!()]));
113        buf.put(Bytes::from(r.reason_phrase));
114        buf.put(Bytes::from_static(&[cr!(), lf!()]));
115        buf.put(Bytes::from(r.headers));
116        buf.put(Bytes::from_static(&[cr!(), lf!()]));
117        buf.put(Bytes::from(r.body));
118        Bytes::from(buf)
119    }
120}