aex 0.1.6

A web server for rust.
Documentation
use ahash::AHashMap;

const MAX_PARAMS: usize = 8;

#[derive(Debug, Clone)]
pub struct SmallParams {
    entries: [(String, String); MAX_PARAMS],
    len: usize,
}

impl Default for SmallParams {
    fn default() -> Self {
        const EMPTY: String = String::new();
        Self {
            entries: [
                (EMPTY, EMPTY),
                (EMPTY, EMPTY),
                (EMPTY, EMPTY),
                (EMPTY, EMPTY),
                (EMPTY, EMPTY),
                (EMPTY, EMPTY),
                (EMPTY, EMPTY),
                (EMPTY, EMPTY),
            ],
            len: 0,
        }
    }
}

impl SmallParams {
    #[inline]
    pub fn new() -> Self {
        Self::default()
    }

    #[inline]
    pub fn with_capacity(_cap: usize) -> Self {
        Self::default()
    }

    #[inline]
    pub fn insert(&mut self, key: String, value: String) {
        if self.len < MAX_PARAMS {
            self.entries[self.len] = (key, value);
            self.len += 1;
        }
    }

    #[inline]
    pub fn get(&self, key: &str) -> Option<&str> {
        for i in 0..self.len {
            if self.entries[i].0 == key {
                return Some(&self.entries[i].1);
            }
        }
        None
    }

    #[inline]
    pub fn len(&self) -> usize {
        self.len
    }

    #[inline]
    pub fn is_empty(&self) -> bool {
        self.len == 0
    }

    #[inline]
    pub fn clear(&mut self) {
        self.len = 0;
    }

    #[inline]
    pub unsafe fn into_map_unchecked(self) -> AHashMap<String, String> {
        let mut map = AHashMap::with_capacity(self.len);
        let mut i = 0usize;
        while i < self.len {
            unsafe {
                let k = std::ptr::read(&self.entries[i].0 as *const String);
                let v = std::ptr::read(&self.entries[i].1 as *const String);
                map.insert(k, v);
            }
            i += 1;
        }
        std::mem::forget(self);
        map
    }
}

impl From<SmallParams> for AHashMap<String, String> {
    fn from(small: SmallParams) -> Self {
        unsafe { small.into_map_unchecked() }
    }
}

#[derive(Debug, Clone)]
pub struct Params {
    pub url: String,
    pub data: Option<AHashMap<String, String>>,
    pub query: AHashMap<String, Vec<String>>,
    pub form: Option<AHashMap<String, Vec<String>>>,
}

impl Params {
    pub fn new(url: String) -> Self {
        let query = url
            .split_once('?')
            .map(|(_, qs)| Self::parse_pairs(qs))
            .unwrap_or_default();

        Self {
            url,
            data: None,
            query,
            form: None,
        }
    }

    pub fn parse_pairs(pairs: &str) -> AHashMap<String, Vec<String>> {
        let mut map: AHashMap<String, Vec<String>> = AHashMap::new();
        for (k, v) in form_urlencoded::parse(pairs.as_bytes()) {
            map.entry(k.into_owned()).or_default().push(v.into_owned());
        }
        map
    }

    pub fn set_form(&mut self, form: &str) {
        self.form = Some(Self::parse_pairs(form));
    }
}