use crate::{handling::routes::Body, utils::mime::Mime};

/// Trait for using datatypes as response bodies
pub trait ResponseBody: Send {
    /// Get a cloned version of the data as a [`Vec<u8>`]
    /// # Ecamples
    /// ```
    /// use http::handling::response::ResponseBody;
    /// let data = "DATA";
    /// assert_eq!(b"DATA".to_vec(), data.get_data());
    /// ```
    fn get_data(&self) -> Vec<u8>;
    /// get the miem type of the data as a [Mime]
    /// # Examples
    /// ```
    /// use http::handling::response::ResponseBody;
    /// use http::utils::mime::Mime;
    /// let data = "DATA";
    /// assert_eq!(Mime::TextPlain, data.get_mime());
    /// ```
    fn get_mime(&self) -> Mime;
    /// get the length in bytes of the data as a [usize]
    /// # Examples
    /// ```
    /// use http::handling::response::ResponseBody;
    /// let data = "DATA";
    /// assert_eq!(4, data.get_len());
    /// ```
    fn get_len(&self) -> usize;
}

impl ResponseBody for Body {
    fn get_data(&self) -> Vec<u8> {
        self.body()
    }
    fn get_mime(&self) -> Mime {
        self.mime_type()
    }

    fn get_len(&self) -> usize {
        self.get_data().len()
    }
}

impl ResponseBody for &str {
    fn get_data(&self) -> Vec<u8> {
        self.as_bytes().to_vec()
    }

    fn get_mime(&self) -> Mime {
        Mime::TextPlain
    }

    fn get_len(&self) -> usize {
        self.len()
    }
}

impl ResponseBody for String {
    fn get_data(&self) -> Vec<u8> {
        self.as_bytes().to_vec()
    }

    fn get_mime(&self) -> Mime {
        Mime::TextPlain
    }

    fn get_len(&self) -> usize {
        self.len()
    }
}