flyer 3.0.4

HTTP framework for rust
Documentation
use std::net::{IpAddr, SocketAddr};

use bytes::Bytes;
use serde::{de::DeserializeOwned};

use crate::{
    cookies::Cookies, request::form::{File, Files, Form}, server::Server, session::Session, utils::{Values, http::Headers, mem::Instance}
};

pub mod form;

#[derive(Clone, Debug)]
pub struct Request {
    pub(crate) server: Instance<Server>,
    pub(crate) addr: SocketAddr,
    pub(crate) protocol: String,
    pub(crate) method: String,
    pub(crate) path: String,
    pub(crate) queries: Values,
    pub(crate) headers: Headers,
    pub(crate) host: String,
    pub(crate) cookies: Cookies,
    pub(crate) session: Session,
    pub(crate) body: Bytes,
    pub(crate) parameters: Values,
    pub(crate) form: Form,
}

impl Into<serde_json::Value> for Request {
    fn into(self) -> serde_json::Value {
        serde_json::json!({
            "ip": &self.queries,
            "protocol": &self.protocol,
            "method": &self.method,
            "path": &self.path,
            "queries": &self.queries,
            "headers": &self.headers,
            "host": &self.host,
            "cookies": &self.cookies,
            "session": &self.session,
            "parameters": &self.parameters,
        })
    }
}

impl Request {
    #[inline]
    pub fn ip(&self) -> IpAddr {
        self
            .addr
            .ip()
    }

    #[inline]
    pub fn protocol(&self) -> String {
        self
            .protocol
            .clone()
    }

    #[inline]
    pub fn method(&self) -> String {
        self
            .path
            .clone()
    }

    #[inline]
    pub fn path(&self) -> String {
        self
            .path
            .clone()
    }

    #[inline]
    pub fn host(&self) -> String {
        self
            .path
            .clone()
    }

    pub fn is_json(&self) -> bool {
        self.header("content-type")
            .split(';')
            .next()
            .map(|mime| mime.trim().eq_ignore_ascii_case("application/json"))
            .unwrap_or(false)
    }

    pub fn parameter(&self, key: impl Into<String>) -> String {
        self
            .parameters
            .get(&key.into())
            .unwrap_or(&String::new())
            .into()
    }

    pub fn query(&self, key: impl Into<String>) -> String {
        self
            .queries
            .get(&key.into())
            .unwrap_or(&String::new())
            .into()
    }

    pub fn query_default<T>(&self, key: impl Into<String>, default: T) -> T
    where
        T: std::str::FromStr
    {
        self.queries
            .get(&key.into())
            .and_then(|v| v.parse::<T>().ok())
            .unwrap_or(default)
    }

    #[inline]
    pub fn session(&self, k: impl Into<String>) -> String {
        self
            .session
            .get(k)
    }

    pub fn values(&self) -> &Values {
        &self
            .form
            .values
    }

    pub fn value(&self, key: impl Into<String>) -> String {
        self
            .form
            .values
            .get(&key.into())
            .unwrap_or(&String::new())
            .into()
    }
    
    #[inline]
    pub fn files(&self) -> &Files {
        &self
            .form
            .files
    }

    pub fn file(&self, k: impl Into<String>) -> Option<&File> {
        self
            .form
            .files
            .get(&k.into())
    }

    #[inline]
    pub fn body(&self) -> &Bytes {
        &self.body
    }

    #[inline]
    pub fn form(&self) -> &Form {
        &self.form
    }

    #[inline]
    pub fn parse_json<J: DeserializeOwned>(&self) -> Result<J, serde_json::Error> {
        serde_json::from_slice(&self.body)
    }

    pub fn header(&self, name: &str) -> String {
        self
            .headers
            .get(&String::from(name))
            .unwrap_or(&String::new())
            .into()
    }

    pub fn cookie(&self, k: impl Into<String>) -> String {
        self
            .cookies
            .get(&k.into())
            .unwrap_or(&String::new())
            .into()
    }

    pub fn cookies(&self) -> &Cookies {
        &self.cookies
    }

    #[inline]
    pub fn server(&self) -> &mut Server {
        self
            .server
            .as_mut()
    }
}