euphony-units 0.1.1

Core types and traits for music composition
Documentation
pub trait Zip {
    type Iter;

    fn zip(self) -> Self::Iter;
}

#[derive(Clone, Copy)]
pub struct ZipIter<T>(T);

macro_rules! zip {
    () => {};
    ($H:ident $(,$T:ident)* $(,)?) => {
        impl<$H: IntoIterator, $($T: IntoIterator,)*> Zip for ($H, $($T,)*) {
            type Iter = ZipIter<($H::IntoIter, $($T::IntoIter,)*)>;

            #[inline]
            #[allow(non_snake_case)]
            fn zip(self) -> Self::Iter {
                let (
                    $H,
                    $(
                        $T,
                    )*
                ) = self;
                ZipIter((
                    $H.into_iter(),
                    $(
                        $T.into_iter(),
                    )*
                ))
            }
        }

        impl<$H: Iterator, $($T: Iterator,)*> Iterator for ZipIter<($H, $($T,)*)> {
            type Item = ($H::Item, $($T::Item,)*);

            #[inline]
            #[allow(non_snake_case)]
            fn next(&mut self) -> Option<Self::Item> {
                let (
                    $H,
                    $(
                        $T,
                    )*
                ) = &mut self.0;
                Some((
                    $H.next()?,
                    $(
                        $T.next()?,
                    )*
                ))
            }
        }

        zip!($($T),*);
    };
}

zip!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z);