easier 0.3.0

making rust easier
Documentation
pub trait Convert<T> {
    type Error;
    /// This converts between types as long as there is a `try_from`
    /// This covers most std types
    /// ```rust
    /// use easier::prelude::*;
    ///  let a: Vec<f64> = [1i32, 2,3].convert().unwrap();
    ///  let b: Vec<i32> = vec![0i8].convert().unwrap();
    /// ```
    fn convert<Tnew: TryFrom<T>>(&self) -> Result<Vec<Tnew>, Self::Error>;

    /// This converts between types replacing unconvertable with the default value.
    /// There must be a `try_from`
    /// This covers many std types
    ///
    /// ```rust
    /// use easier::prelude::*;
    ///  let a: Vec<f64> = [1i32, 2,3].convert_default();
    ///  let b: Vec<i32> = vec![0i8].convert_default();
    /// ```
    fn convert_default<Tnew: TryFrom<T> + Default>(&self) -> Vec<Tnew>;

    /// This converts between types replacing unconvertable with the given value.
    /// There must be a `try_from`
    /// This covers many std types
    ///
    /// ```rust
    /// use easier::prelude::*;
    ///  let a: Vec<f64> = [1i32, 2,3].convert_or(100.45);
    /// ```
    fn convert_or<Tnew: TryFrom<T> + Clone>(&self, fallback: Tnew) -> Vec<Tnew>;
}

impl<T> Convert<T> for [T]
where
    T: Clone,
{
    type Error = String;
    fn convert_default<Tnew>(&self) -> Vec<Tnew>
    where
        Tnew: TryFrom<T>,
        Tnew: Default, //  <Tnew as TryFrom<T>>::Error: Display,
    {
        self.iter()
            .map(|a| Tnew::try_from(a.clone()).unwrap_or_default())
            .collect()
    }

    fn convert<Tnew: TryFrom<T>>(&self) -> Result<Vec<Tnew>, Self::Error> {
        let mut vec = Vec::with_capacity(self.len());
        for (i, item) in self.iter().enumerate() {
            match Tnew::try_from(item.clone()) {
                Ok(item) => vec.push(item),
                Err(_) => return Err(format!("Could not convert item at index {i}")),
            }
        }
        Ok(vec)
    }

    fn convert_or<Tnew: TryFrom<T> + Clone>(&self, fallback: Tnew) -> Vec<Tnew> {
        self.iter()
            .map(|a| Tnew::try_from(a.clone()).unwrap_or(fallback.clone()))
            .collect()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn convert_default() {
        let a = [1u32, 2, 3];
        assert_eq!(a.convert_default::<f64>(), [1., 2., 3.]);
        let b: Vec<u8> = a.convert_default();
        assert_eq!(b, [1u8, 2, 3]);

        let fail = vec![300u32, 2, 3];
        let b: Vec<u8> = fail.convert_default();
        assert_eq!(b, vec![0u8, 2, 3]);
    }

    #[test]
    fn convert_or() {
        let a = [1u32, 2, 3];
        assert_eq!(a.convert_or::<f64>(0.), [1., 2., 3.]);
        let b: Vec<u8> = a.convert_default();
        assert_eq!(b, [1u8, 2, 3]);

        let fail = vec![300u32, 2, 3];
        let b: Vec<u8> = fail.convert_or(1);
        assert_eq!(b, vec![1u8, 2, 3]);
    }

    #[test]
    fn convert() {
        let a = [1u32, 2, 3];
        assert_eq!(a.convert::<f64>(), Ok(vec![1., 2., 3.]));
        let b = a.convert::<u8>();
        assert_eq!(b, Ok(vec![1u8, 2, 3]));

        let fail = vec![300u32, 2, 3];
        let b = fail.convert::<u8>();
        assert_eq!(b.is_err(), true);
    }
}