1#[cfg(test)]
2mod tests;
3use std::iter::FusedIterator;
4pub trait Zip: IntoIterator + Sized {
10 fn zip_fill<R, F>(self, r: R, fill: F) -> Filler<Self::IntoIter, R::IntoIter, F>
24 where
25 R: IntoIterator<Item = Self::Item>,
26 F: FnMut() -> Self::Item,
27 {
28 Filler {
29 q: self.into_iter(),
30 r: r.into_iter(),
31 fill,
32 }
33 }
34 fn zip_fill_default<R>(self, r: R) -> Filler<Self::IntoIter, R::IntoIter, fn() -> Self::Item>
43 where
44 R: IntoIterator<Item = Self::Item>,
45 Self::Item: Default,
46 {
47 Filler {
48 q: self.into_iter(),
49 r: r.into_iter(),
50 fill: Self::Item::default,
51 }
52 }
53 fn zip_fill_with<R>(self, r: R, item: Self::Item) -> FillerWith<Self::IntoIter, R::IntoIter>
63 where
64 R: IntoIterator<Item = Self::Item>,
65 Self::Item: Clone,
66 {
67 FillerWith {
68 q: self.into_iter(),
69 r: r.into_iter(),
70 item,
71 }
72 }
73}
74
75impl<I: IntoIterator> Zip for I {}
76
77#[derive(Debug)]
78pub struct Filler<Q, R, F>
80where
81 Q: Iterator,
82 R: Iterator<Item = Q::Item>,
83 F: FnMut() -> Q::Item,
84{
85 q: Q,
86 r: R,
87 fill: F,
88}
89
90#[derive(Debug)]
91pub struct FillerWith<Q: Iterator, R: Iterator<Item = Q::Item>> {
93 q: Q,
94 r: R,
95 item: Q::Item,
96}
97
98impl<Q, R> Iterator for FillerWith<Q, R>
99where
100 Q: Iterator,
101 R: Iterator<Item = Q::Item>,
102 Q::Item: Clone,
103{
104 type Item = (Q::Item, Q::Item);
105 fn next(&mut self) -> Option<Self::Item> {
106 match (self.q.next(), self.r.next()) {
107 (None, None) => None,
108 (Some(q), None) => Some((q, self.item.clone())),
109 (None, Some(r)) => Some((self.item.clone(), r)),
110 (Some(q), Some(r)) => Some((q, r)),
111 }
112 }
113
114 fn size_hint(&self) -> (usize, Option<usize>) {
115 size_hint(self.q.size_hint(), self.r.size_hint())
116 }
117}
118
119impl<Q, R, F> Iterator for Filler<Q, R, F>
120where
121 Q: Iterator,
122 R: Iterator<Item = Q::Item>,
123 F: FnMut() -> Q::Item,
124{
125 type Item = (Q::Item, Q::Item);
126 fn next(&mut self) -> Option<Self::Item> {
127 match (self.q.next(), self.r.next()) {
128 (None, None) => None,
129 (Some(q), None) => Some((q, (self.fill)())),
130 (None, Some(r)) => Some(((self.fill)(), r)),
131 (Some(q), Some(r)) => Some((q, r)),
132 }
133 }
134 fn size_hint(&self) -> (usize, Option<usize>) {
135 size_hint(self.q.size_hint(), self.r.size_hint())
136 }
137}
138
139#[inline]
140fn size_hint(
141 (min_a, max_a): (usize, Option<usize>),
142 (min_b, max_b): (usize, Option<usize>),
143) -> (usize, Option<usize>) {
144 let min = usize::max(min_a, min_b); let max = if let (Some(a), Some(b)) = (max_a, max_b) {
146 Some(usize::max(a, b))
147 } else {
148 None
149 };
150 (min, max)
151}
152
153impl<Q, R> ExactSizeIterator for FillerWith<Q, R>
154where
155 Q: ExactSizeIterator,
156 R: ExactSizeIterator<Item = Q::Item>,
157 Q::Item: Clone,
158{}
159impl<Q, R> FusedIterator for FillerWith<Q, R>
160where
161 Q: FusedIterator,
162 R: FusedIterator<Item = Q::Item>,
163 Q::Item: Clone,
164{}
165
166impl<Q, R, F> ExactSizeIterator for Filler<Q, R, F>
167where
168 Q: ExactSizeIterator,
169 R: ExactSizeIterator<Item = Q::Item>,
170 F: FnMut() -> Q::Item,
171{}
172
173impl<Q, R, F> FusedIterator for Filler<Q, R, F>
174where
175 Q: FusedIterator,
176 R: FusedIterator<Item = Q::Item>,
177 F: FnMut() -> Q::Item,
178{}