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
use crate::status_code::get_reason_phrase_by_status_code; use crate::{Body, Headers, HttpVersion, ReasonPhrase, StatusCode}; use bytes::{BufMut, Bytes}; use std::error::Error; use std::fmt; #[derive(Debug)] pub enum ResponseBuilderError { HttpVersionIsNone, StatusCodeIsNone, ReasonPhraseIsNone, HeadersIsNone, BodyIsNone, } impl fmt::Display for ResponseBuilderError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { ResponseBuilderError::HttpVersionIsNone => write!(f, "HTTP version is None."), ResponseBuilderError::StatusCodeIsNone => write!(f, "Status code is None."), ResponseBuilderError::ReasonPhraseIsNone => write!(f, "Reason phrase is None."), ResponseBuilderError::HeadersIsNone => write!(f, "Headers is None."), ResponseBuilderError::BodyIsNone => write!(f, "Body is None."), } } } impl Error for ResponseBuilderError {} #[derive(Debug, Clone)] pub struct ResponseBuilder { http_version: Option<HttpVersion>, status_code: Option<StatusCode>, reason_phrase: Option<ReasonPhrase>, headers: Option<Headers>, body: Option<Body>, } impl ResponseBuilder { pub fn http_version(&mut self, http_version: HttpVersion) -> &mut Self { self.http_version = Some(http_version); self } pub fn status_code(&mut self, status_code: StatusCode) -> &mut Self { if let Some(reason_phrase) = get_reason_phrase_by_status_code(&status_code) { self.reason_phrase = Some(reason_phrase) } self.status_code = Some(status_code); self } pub fn reason_phrase(&mut self, reason_phrase: ReasonPhrase) -> &mut Self { self.reason_phrase = Some(reason_phrase); self } pub fn headers(&mut self, headers: Headers) -> &mut Self { self.headers = Some(headers); self } pub fn body(&mut self, body: Body) -> &mut Self { self.body = Some(body); self } pub fn build(self) -> Result<Response, ResponseBuilderError> { let http_version = self .http_version .ok_or(ResponseBuilderError::HttpVersionIsNone)?; let status_code = self .status_code .ok_or(ResponseBuilderError::StatusCodeIsNone)?; let reason_phrase = self .reason_phrase .ok_or(ResponseBuilderError::ReasonPhraseIsNone)?; let headers = self.headers.ok_or(ResponseBuilderError::HeadersIsNone)?; let body = self.body.ok_or(ResponseBuilderError::BodyIsNone)?; Ok(Response { http_version, status_code, reason_phrase, headers, body, }) } } #[derive(Debug, Clone)] pub struct Response { http_version: HttpVersion, status_code: StatusCode, reason_phrase: ReasonPhrase, headers: Headers, body: Body, } impl Response { pub fn builder() -> ResponseBuilder { ResponseBuilder { http_version: None, status_code: None, reason_phrase: None, headers: None, body: None, } } } impl From<Response> for Bytes { fn from(r: Response) -> Self { let mut buf = Vec::<u8>::new(); buf.put(Bytes::from(r.http_version)); buf.put(Bytes::from_static(&[sp!()])); buf.put(Bytes::from(r.status_code)); buf.put(Bytes::from_static(&[sp!()])); buf.put(Bytes::from(r.reason_phrase)); buf.put(Bytes::from_static(&[rf!(), lf!()])); buf.put(Bytes::from(r.headers)); buf.put(Bytes::from_static(&[rf!(), lf!()])); buf.put(Bytes::from(r.body)); Bytes::from(buf) } }