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
use crate::{Body, Headers, HttpVersion, Method, RequestUri}; use std::error::Error; use std::fmt; use std::ops::Add; #[derive(Debug, Clone)] pub enum RequestError { MethodIsNone, RequestUriIsNone, HttpVersionIsNone, HeadersIsNone, BodyIsNone, InvalidRequestLine, InvalidHeader, InvalidHeaderValue, } impl fmt::Display for RequestError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { RequestError::MethodIsNone => write!(f, "Method is None."), RequestError::RequestUriIsNone => write!(f, "Request URI is None."), RequestError::HttpVersionIsNone => write!(f, "HTTP version is None."), RequestError::HeadersIsNone => write!(f, "Headers is None."), RequestError::BodyIsNone => write!(f, "Body is None."), RequestError::InvalidRequestLine => write!(f, "Invalid request line."), RequestError::InvalidHeader => write!(f, "Invalid header."), RequestError::InvalidHeaderValue => write!(f, "Invalid header value."), } } } impl Error for RequestError {} #[derive(Debug, Clone)] pub struct RequestPart { method: Option<Method>, request_uri: Option<RequestUri>, http_version: Option<HttpVersion>, headers: Option<Headers>, body: Option<Body>, } impl RequestPart { pub fn build(self) -> Result<Request, RequestError> { let method = self.method.ok_or(RequestError::MethodIsNone)?; let request_uri = self.request_uri.ok_or(RequestError::RequestUriIsNone)?; let http_version = self.http_version.ok_or(RequestError::HttpVersionIsNone)?; let headers = self.headers.ok_or(RequestError::HeadersIsNone)?; let body = self.body.ok_or(RequestError::BodyIsNone)?; Ok(Request { method, request_uri, http_version, headers, body, }) } } impl Add<RequestPart> for RequestPart { type Output = Self; fn add(mut self, other: Self) -> Self { self.method = self.method.or(other.method); self.request_uri = self.request_uri.or(other.request_uri); self.http_version = self.http_version.or(other.http_version); self.headers = match (self.headers, other.headers) { (a, None) => a, (None, b) => b, (Some(a), Some(b)) => Some(a + b), }; self.body = match (self.body, other.body) { (a, None) => a, (None, b) => b, (Some(a), Some(b)) => Some(a + b), }; self } } #[derive(Debug, Clone)] pub struct Request { method: Method, request_uri: RequestUri, http_version: HttpVersion, headers: Headers, body: Body, }