1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
/*! Powerful macro for creating iterators on the fly. See [`iterate`] for details. */ #![no_std] use core::fmt; use core::fmt::Debug; use core::fmt::Formatter; use core::iter::FusedIterator; /** Create an iterator on the fly The `iterate` macro creates an iterator on the fly: ``` use iterate::iterate; let mut iterator = iterate![1, 2, 3]; assert_eq!(iterator.next(), Some(1)); assert_eq!(iterator.next(), Some(2)); assert_eq!(iterator.next(), Some(3)); assert_eq!(iterator.next(), None); ``` The iterator lazily evaluates each of its arguments, one at a time: ``` use std::cell::Cell; use iterate::iterate; let cell = Cell::new(0); let cell = &cell; let mut iterator = iterate![ {cell.set(cell.get() + 1); 1}, {cell.set(cell.get() + 1); 2}, {cell.set(cell.get() + 1); 3}, ]; assert_eq!(cell.get(), 0); assert_eq!(iterator.next(), Some(1)); assert_eq!(cell.get(), 1); assert_eq!(iterator.next(), Some(2)); assert_eq!(cell.get(), 2); assert_eq!(iterator.next(), Some(3)); assert_eq!(cell.get(), 3); assert_eq!(iterator.next(), None); ``` Most usefully, `iterate` can capture any other [`IntoIterator`] type and iterate over it, by prefixing the value with `..`: ``` use iterate::iterate; let range = 0..5; let vec = vec![4, 1, 2, 3]; // Iterate captures its arguments by move, and evaluates them lazily, so we // need to ensure that the vec is captured by reference let vec = &vec; let iterator = iterate![ 1, ..range, ..vec.iter().copied(), 10 ]; let result: Vec<i32> = iterator.collect(); assert_eq!(result, [ 1, 0, 1, 2, 3, 4, 4, 1, 2, 3, 10, ]) ``` # Eager and Lazy evaluation `iterate` tries to be smart about when it evaluates its arguments eagerly vs lazily. In general it tries to evaluate them lazily, but in cases where it's sure there will be no side effects, it evaluates `..iter` arguments eagerly. It does this so that it can provide a more reliable `size_hint`. */ pub use iterate_proc_macro::iterate; /// The [`iterate`] macro produces a type that uses unsafe in the /// implementation. It is therefore critical that users of the library not /// have access to the fields of the type. Because the type is defined locally, /// the only way to do this is to wrap it in another type that forwards the /// iterator implementation #[derive(Clone, Default)] #[doc(hidden)] pub struct ConcealedIterator<I> { iter: I, } impl<I: Debug> Debug for ConcealedIterator<I> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { self.iter.fmt(f) } } impl<I: Iterator> Iterator for ConcealedIterator<I> { type Item = I::Item; fn next(&mut self) -> Option<Self::Item> { self.iter.next() } fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() } } impl<I: DoubleEndedIterator> DoubleEndedIterator for ConcealedIterator<I> { fn next_back(&mut self) -> Option<Self::Item> { self.iter.next_back() } } impl<I: ExactSizeIterator> ExactSizeIterator for ConcealedIterator<I> { fn len(&self) -> usize { self.iter.len() } } impl<I: FusedIterator> FusedIterator for ConcealedIterator<I> {} #[doc(hidden)] #[inline] pub fn conceal<I: Iterator>(iter: I) -> ConcealedIterator<I> { ConcealedIterator { iter } }