bend/
utils.rs

1/// A macro for creating iterators that can have statically known
2/// different types. Useful for iterating over tree children, where
3/// each tree node variant yields a different iterator type.
4#[macro_export]
5macro_rules! multi_iterator {
6  ($Iter:ident { $($Variant:ident),* $(,)? }) => {
7    #[derive(Debug, Clone)]
8    enum $Iter<$($Variant),*> {
9      $($Variant { iter: $Variant }),*
10    }
11
12    impl<$($Variant),*> $Iter<$($Variant),*> {
13      $(
14        #[allow(non_snake_case)]
15        fn $Variant(iter: impl IntoIterator<IntoIter = $Variant>) -> Self {
16          $Iter::$Variant { iter: iter.into_iter() }
17        }
18      )*
19    }
20
21    impl<T, $($Variant: Iterator<Item = T>),*> Iterator for $Iter<$($Variant),*> {
22      type Item = T;
23      fn next(&mut self) -> Option<T> {
24        match self { $($Iter::$Variant { iter } => iter.next()),* }
25      }
26
27      fn size_hint(&self) -> (usize, Option<usize>) {
28        match self { $($Iter::$Variant { iter } => iter.size_hint()),* }
29      }
30    }
31
32    impl<T, $($Variant: DoubleEndedIterator<Item = T>),*> DoubleEndedIterator for $Iter<$($Variant),*> {
33      fn next_back(&mut self) -> Option<T> {
34        match self { $($Iter::$Variant { iter } => iter.next_back()),* }
35      }
36    }
37  };
38}