use std::{
    borrow::Cow,
    collections::HashMap,
    ops::{Deref, DerefMut},
};

pub struct Form<'a>(HashMap<Cow<'a, str>, Cow<'a, str>>);

impl<'a> Form<'a> {
    #[must_use]
    pub fn new<const BN: usize>(entries: [(&'a str, &'a str); BN]) -> Self {
        Self(HashMap::from(
            entries.map(|(k, v)| (Cow::from(k), Cow::from(v))),
        ))
    }

    #[must_use]
    pub fn parse(data: &str) -> Self {
        Self(
            data.lines()
                .filter_map(|a| {
                    a.split_once('=')
                        .map(|(a, b)| (Cow::from(a.to_string()), Cow::from(b.to_string())))
                })
                .collect(),
        )
    }

    #[must_use]
    pub fn format(&self) -> String {
        self.0
            .iter()
            .map(|(k, v)| format!("{k}={v}"))
            .collect::<Vec<String>>()
            .join("&")
    }
}

impl<'a> Deref for Form<'a> {
    type Target = HashMap<Cow<'a, str>, Cow<'a, str>>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl<'a> DerefMut for Form<'a> {
    fn deref_mut(&mut self) -> &mut HashMap<Cow<'a, str>, Cow<'a, str>> {
        &mut self.0
    }
}
