[][src]Macro unzip_n::unzip_n

unzip_n!() { /* proc-macro */ }

Generates a trait and its implementation to "unzip" an iterator of N-sized tuple into N collections, where N is passed to the macro, like unzip_n(10):

// Note that visiblity modifier is accepted!
unzip_n!(pub(crate) 2);
unzip_n!(5);
unzip_n!(3);

let v = vec![(1, 2), (3, 4)];
let (s1, s2): (HashSet<_>, HashSet<_>) = v.clone().into_iter().unzip_n();
println!("{:?}, {:?}", s1, s2);

let (v1, v2) = v.into_iter().unzip_n_vec();
println!("{:?}, {:?}", v1, v2);

let v = vec![(1, 2, 3, 4, 5), (6, 7, 8, 9, 10)];
let (v1, v2, v3, v4, v5) = v.into_iter().unzip_n_vec();
println!("{:?}, {:?}, {:?}, {:?}, {:?}", v1, v2, v3, v4, v5);

For example, unzip_n(3) will produce a code like the following:

///Extension trait for unzipping iterators over tuples of size 3.
trait Unzip3<Type_0, Type_1, Type_2> {
    /// Unzips an iterator over tuples into a tuple of collections.
    fn unzip_n<Collection_0, Collection_1, Collection_2>(
        self,
    ) -> (Collection_0, Collection_1, Collection_2)
    where
        Collection_0: Default + Extend<Type_0>,
        Collection_1: Default + Extend<Type_1>,
        Collection_2: Default + Extend<Type_2>;
    /// Unzips an iterator over tuples into a tuple of vectors.
    fn unzip_n_vec(self) -> (Vec<Type_0>, Vec<Type_1>, Vec<Type_2>)
    where
        Self: Sized,
    {
        self.unzip_n()
    }
}

impl<Iter, Type_0, Type_1, Type_2> Unzip3<Type_0, Type_1, Type_2> for Iter
where
    Iter: Iterator<Item = (Type_0, Type_1, Type_2)>,
{
    fn unzip_n<Collection_0, Collection_1, Collection_2>(
        self,
    ) -> (Collection_0, Collection_1, Collection_2)
    where
        Collection_0: Default + Extend<Type_0>,
        Collection_1: Default + Extend<Type_1>,
        Collection_2: Default + Extend<Type_2>,
    {
        let mut container_0 = Collection_0::default();
        let mut container_1 = Collection_1::default();
        let mut container_2 = Collection_2::default();
        self.for_each(|(val_0, val_1, val_2)| {
            container_0.extend(Some(val_0));
            container_1.extend(Some(val_1));
            container_2.extend(Some(val_2));
        });
        (container_0, container_1, container_2)
    }
}