hans-http 0.2.0

Writing a http request and http response safely.
Documentation
use crate::prelude::*;

#[derive(Debug, PartialEq)]
pub enum RequestMethod {
    GET,
    POST,
    PUT,
    DELETE,
    PATCH,
}

impl ToString for RequestMethod {
    fn to_string(&self) -> String {
        match self {
            RequestMethod::GET => String::from("GET"),
            RequestMethod::POST => String::from("POST"),
            RequestMethod::PUT => String::from("PUT"),
            RequestMethod::DELETE => String::from("DELETE"),
            RequestMethod::PATCH => String::from("PATCH"),
        }
    }
}

#[derive(Debug, PartialEq)]
pub struct HttpRequest {
    pub request_method: RequestMethod,
    pub url: String,
    pub headers: Vec<(String, String)>,
    pub body: Option<String>,
}

impl ToString for HttpRequest {
    fn to_string(&self) -> String {
        let request_method = self.request_method.to_string();
        let headers = self.headers.iter().map(|header| format!("{}: {}", header.0, header.1)).collect::<Vec<String>>();
        let headers = headers.join("\r\n");

        if let Some(body) = &self.body {
            format!("{} {} HTTP/1.1\r\n{}\r\n\r\n{}", request_method, self.url, headers, body)
        } else {
            format!("{} {} Http/1.1\r\n{}", request_method, self.url, headers)
        }
    }
}

#[derive(Debug)]
pub struct HttpRequestBuilder {
    request_method: Option<RequestMethod>,
    url: Option<String>,
    headers: Vec<(String, String)>,
    body: Option<String>,
}

impl HttpRequestBuilder {
    pub fn new() -> Self {
        Self {
            request_method: None,
            url: None,
            headers: Vec::new(),
            body: None,
        }
    }
    pub fn set_request_method(mut self, method: RequestMethod) -> Self {
        self.request_method = Some(method);
        self
    }
    pub fn set_url(mut self, url: &str) -> Self {
        self.url = Some(url.to_string());
        self
    }
    pub fn add_header(mut self, header: (&str, &str)) -> Self {
        self.headers.push((header.0.to_string(), header.1.to_string()));
        self
    }
    pub fn set_body(mut self, content: &str) -> Self {
        self.body = Some(content.to_string());
        self
    }
    pub fn build(self) -> Result<HttpRequest> {
        Ok(HttpRequest {
            request_method: self.request_method.ok_or(Error::NotSetRequestMethod)?,
            url: self.url.ok_or(Error::NotSetUrl)?,
            headers: self.headers,
            body: self.body,
        })
    }
}