lest 0.2.1

A modular approach to a web server. Based on actix-web.
Documentation
use std::collections::HashMap;

use actix_web::{web::Payload, HttpRequest};

use crate::types::method::Method;

use super::{form::Form, ua::UserAgent};

#[allow(dead_code)]
/// This Request struct is a representation of an HTTP request.
pub struct Request {
    pub host: String,
    pub port: u16,
    pub method: Method,
    pub user_agent: UserAgent,
    pub headers: Vec<(String, String)>,
    pub body: String,
    pub query: Vec<(String, String)>,
    pub path: String,
    pub actix: HttpRequest,
    pub stream: Payload,
    pub params: HashMap<String, String>,
}

impl Request {
    /// (Internal) Create a new Request with the specified method, host, port, user agent, headers, body, query, path, actix request, and parameters.
    pub fn new(method: Method, host: String, port: u16, user_agent: UserAgent, headers: Vec<(String, String)>, body: String, query: Vec<(String, String)>, path: String, actix: HttpRequest, stream: Payload, params: HashMap<String, String>) -> Self {
        Request {
            host,
            port,
            method,
            user_agent,
            headers,
            body,
            query,
            path,
            actix,
            stream,
            params,
        }
    }

    /// Get a header from the request.
    pub fn get_header(&self, key: &str) -> Option<&str> {
        for (header_key, header_value) in &self.headers {
            if header_key == key {
                return Some(header_value);
            }
        }
        None
    }

    /// Get a query parameter from the request.
    pub fn get_query(&self, key: &str) -> Option<&str> {
        for (query_key, query_value) in &self.query {
            if query_key == key {
                return Some(query_value);
            }
        }
        None
    }

    /// Get a segment from the request path.
    pub fn get_segment(&self, index: usize) -> Option<&str> {
        let segments: Vec<&str> = self.path.split("/").collect();
        if segments.len() > index {
            return Some(segments[index]);
        }
        None
    }

    /// Get a parameter from the request.
    pub fn get_param(&self, name: &str) -> Option<&str> {
        return self.params.get(name).map(|v| v.as_str());
    }

    /// Set a parameter in the request.
    pub fn set_param(&mut self, index: &str, value: &str) {
        self.params.entry(index.to_string()).or_insert(value.to_string());
    }

    /// Get the Actix request.
    pub fn get_actix(&self) -> &HttpRequest {
        &self.actix
    }

    /// Get the Actix request as mutable.
    pub fn get_actix_mut(&mut self) -> &mut HttpRequest {
        &mut self.actix
    }

    /// Get the body of the request as JSON.
    pub fn body_as_json(&self) -> serde_json::Value {
        serde_json::from_str(&self.body).unwrap()
    }

    /// Get the body of the request as text.
    pub fn body_as_text(&self) -> String {
        self.body.clone()
    }

    /// Get the body of the request as a form.
    pub fn body_as_form(&self) -> Form {
        Form::decode(&self.body, self.get_header("Content-Type").unwrap())
    }
}