easier 0.3.0

making rust easier
Documentation
use std::{
    collections::{HashMap, HashSet},
    hash::Hash,
};

pub trait ToCollectionIteratorExtension: Iterator {
    /// Converts an iterator into a `Vec`
    ///
    /// Easier than calling `.collect::<Vec<_>>()` just do `.to_vec()` on an Iterator
    /// ```rust
    /// use easier::prelude::*;
    /// let vec=[1,2,3].iter().to_vec();
    /// ```
    fn to_vec(self) -> Vec<Self::Item>
    where
        Self: Sized,
    {
        self.collect()
    }
    /// Converts an iterator into a `HashSet`
    /// Easier than calling `.collect::<HashSet<_>>()` just do `.to_hashset()` on an Iterator
    /// ```rust
    /// use easier::prelude::*;
    /// let hs=[1,2,3].iter().to_hashset();
    /// ```
    fn to_hashset(self) -> HashSet<Self::Item>
    where
        Self::Item: Eq + Hash,
        Self: Sized,
    {
        self.collect()
    }

    /// Converts an iterator into a `HashMap`
    /// Easier than calling `.into_iter().collect::<HashMap<_,_>>()` just do `.to_hashmap()` on an Iterator
    /// Note the use of `into_iter()` not `iter()`
    /// ```rust
    /// use easier::prelude::*;
    /// let hm=[(1,2),(3,4)].into_iter().to_hashmap();
    /// ```
    fn to_hashmap<K, V>(self) -> HashMap<K, V>
    where
        Self: Iterator<Item = (K, V)>,
        K: Eq + Hash + Clone,
        Self: Sized,
    {
        self.collect()
    }
}

impl<I> ToCollectionIteratorExtension for I where I: Iterator {}

pub trait ToCollectionClonedIteratorExtension: Iterator {
    type ToCloned;
    fn to_vec_cloned(self) -> Vec<Self::ToCloned>;
}

impl<'a, T, I> ToCollectionClonedIteratorExtension for I
where
    I: Iterator<Item = &'a T>,
    T: 'a + Clone,
{
    type ToCloned = T;

    fn to_vec_cloned(self) -> Vec<Self::ToCloned> {
        self.cloned().collect()
    }
}

pub trait ToCollectionIntoIteratorExtension: IntoIterator {
    ///Easier than calling `.into_iter().collect::<Vec<_>>()`
    fn into_vec(self) -> Vec<Self::Item>;
    ///Easier than calling `.into_iter().collect::<HashSet<_>>()`
    fn into_hashset(self) -> HashSet<Self::Item>
    where
        Self::Item: Eq + Hash;
}

pub trait ToCollectionIntoIteratorClonedExtension: IntoIterator {
    type ToB;
    fn into_vec_cloned(self) -> Vec<Self::ToB>;
}

impl<'a, T, I> ToCollectionIntoIteratorClonedExtension for I
where
    I: IntoIterator<Item = &'a T>,
    T: 'a + Clone,
{
    type ToB = T;
    fn into_vec_cloned(self) -> Vec<T> {
        self.into_iter().cloned().collect()
    }
}

impl<T, I> ToCollectionIntoIteratorExtension for I
where
    I: IntoIterator<Item = T>,
{
    fn into_vec(self) -> Vec<T> {
        self.into_iter().collect()
    }

    fn into_hashset(self) -> HashSet<Self::Item>
    where
        Self::Item: Eq + Hash,
    {
        self.into_iter().collect()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    use std::collections::HashSet;

    #[test]
    fn to_vec() {
        //this already exists
        let a = [1, 2];
        let b = a.to_vec();
        assert_eq!(b, vec![1, 2]);

        //new tests
        //iter borrow
        let b = a.iter().to_vec();
        assert_eq!(b, vec![&1, &2]);
        //iter
        let b = a.into_iter().to_vec();
        assert_eq!(b, vec![1, 2]);

        //map
        let a = vec![1, 2];
        let b = a.iter().map(|a| *a * 2).to_vec();
        assert_eq!(b, vec![2, 4]);

        //hashset
        let mut b = HashSet::<u8>::from_iter([1, 2, 4]).into_vec();
        b.sort();
        assert_eq!(b, vec![1, 2, 4]);

        //non clone items
        #[derive(Debug, PartialEq, Eq)]
        struct A;
        let a = [A {}, A {}];
        let b = a.into_vec();
        assert_eq!(b, vec![A {}, A {}]);
        let c = [A {}, A {}];
        let d = c.into_iter().collect::<Vec<_>>();
        assert_eq!(b, d);

        //hashset
        let a = [1, 2, 3, 2, 4, 2, 5];
        let b = a.iter().to_hashset();
        assert_eq!(b.len(), 5);
        let mut bsorted = b.into_vec_cloned();
        bsorted.sort();
        assert_eq!(bsorted, [1, 2, 3, 4, 5]);

        let c = a.into_hashset();
        let mut csorted = c.into_vec();
        csorted.sort();
        assert_eq!(csorted, [1, 2, 3, 4, 5]);

        //strings
        let a = vec![String::from("hello"), String::from("there")];
        let b = a.iter().to_vec_cloned();
        assert_eq!(a, b);
    }

    #[test]
    fn to_hashmap() {
        let a = [(1, 2), (3, 4), (1, 55)]; //2 gets overridden by 5
        let b = a.into_iter().to_hashmap();

        assert_eq!(b.len(), 2);
        assert_eq!(b[&3], 4);
        assert_eq!(b[&1], 55);
    }
}