http_protocol/response/
mod.rs1use 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}