orx_iterable/
iterable.rs

1use crate::transformations::{
2    Chained, Cloned, Copied, Enumerated, FilterMapped, Filtered, FlatMapped, Flattened, Fused,
3    Mapped, MappedWhile, Reversed, Skipped, SkippedWhile, SteppedBy, Taken, TakenWhile, Zipped,
4};
5
6/// An `Iterable` is any type which can return a new iterator that yields elements of the associated type [`Item`] every time [`iter`] method is called.
7///
8/// [`Item`]: crate::Iterable::Item
9/// [`iter`]: crate::Iterable::iter
10///
11/// Notice that this is the least restrictive and most general iterable definition.
12///
13/// Three categories of types implement the Iterable trait:
14///
15/// * references of collections
16/// * cloneable iterators
17/// * lazy generators
18///
19/// # Auto Implementations
20///
21/// ## References of collections
22///
23/// First, consider a collection type `X` storing elements of type `T`.
24/// Provided that the following implementation is provided:
25///
26/// * `&X: IntoIterator<Item = &T>`
27///
28/// Then, `&X` implements `Iterable<Item = &T>`.
29///
30/// In other words, a reference of a collection is an `Iterable`.
31///
32/// ## Cloneable iterators
33///
34/// Second, consider an iterator that can be cloned; i.e., `Iterator + Clone`.
35/// This iterator can be converted into an `Iterable` which can be iterated over
36/// repeatedly by calling `into_iterable` method.
37///
38/// ## Lazy Generators
39///
40/// Third, consider types iterators of which create values on the fly during the
41/// iteration. One such example is the range.
42/// Consider, for instance, the range 3..7.
43/// Although it looks like a collection, it does not hold elements (3, 4, 5, 6) anywhere in memory. These elements are produced on the fly during the iteration.
44/// `Iterable` trait implementations for the ranges are provided in this crate.
45///
46/// For similar custom types, the trait needs to be implemented explicitly.
47///
48/// # Examples
49///
50/// ```
51/// use orx_iterable::*;
52/// use arrayvec::ArrayVec;
53/// use smallvec::{smallvec, SmallVec};
54/// use std::collections::{BTreeSet, BinaryHeap, HashSet, LinkedList, VecDeque};
55///
56/// struct Stats {
57///     count: usize,
58///     mean: i64,
59///     std_dev: i64,
60/// }
61///
62/// /// we need multiple iterations over numbers to compute the stats
63/// fn statistics(numbers: impl Iterable<Item = i64>) -> Stats {
64///     let count = numbers.iter().count() as i64;
65///     let sum = numbers.iter().sum::<i64>();
66///     let mean = sum / count;
67///     let sum_sq_errors: i64 = numbers.iter().map(|x| (x - mean) * (x - mean)).sum();
68///     let std_dev = f64::sqrt(sum_sq_errors as f64 / (count - 1) as f64) as i64;
69///     Stats {
70///         count: count as usize,
71///         mean,
72///         std_dev,
73///     }
74/// }
75///
76/// // collections as Iterable
77///
78/// let x = [3, 5, 7];
79/// statistics(x.copied()); // see Iterable's transformation methods such as copied, mapped, etc.
80///
81/// let x = vec![3, 5, 7];
82/// statistics(x.copied());
83///
84/// let x = LinkedList::from_iter([3, 5, 7]);
85/// statistics(x.copied());
86///
87/// let x = VecDeque::from_iter([3, 5, 7]);
88/// statistics(x.copied());
89///
90/// let x = HashSet::<_>::from_iter([3, 5, 7]);
91/// statistics(x.copied());
92///
93/// let x = BTreeSet::from_iter([3, 5, 7]);
94/// statistics(x.copied());
95///
96/// let x = BinaryHeap::from_iter([3, 5, 7]);
97/// statistics(x.copied());
98///
99/// let x: SmallVec<[_; 128]> = smallvec![3, 5, 7];
100/// statistics(x.copied());
101///
102/// let mut x = ArrayVec::<_, 16>::new();
103/// x.extend([3, 5, 7]);
104/// statistics(x.copied());
105///
106/// // cloneable iterators as Iterable
107///
108/// let x = (0..10).map(|x| x * 2).into_iterable();
109/// statistics(x);
110///
111/// let x = vec![1, 2, 3];
112/// let y = x
113///     .iter()
114///     .copied()
115///     .filter(|x| x % 2 == 1)
116///     .flat_map(|x| [-x, x])
117///     .into_iterable();
118/// statistics(y);
119///
120/// // lazy generators as Iterable
121///
122/// statistics(7..21i64);
123/// ```
124///
125/// The following example represents an explicit implementation of the Iterable
126/// trait for a lazy generator, which generates a sequence of Fibonacci numbers
127/// up to a set bound.
128///
129/// ```
130/// use orx_iterable::*;
131///
132/// struct FibUntilIter {
133///     curr: u32,
134///     next: u32,
135///     until: u32,
136/// }
137///
138/// impl Iterator for FibUntilIter {
139///     type Item = u32;
140///
141///     fn next(&mut self) -> Option<Self::Item> {
142///         let current = self.curr;
143///         self.curr = self.next;
144///         self.next = current + self.next;
145///         match current > self.until {
146///             false => Some(current),
147///             true => None,
148///         }
149///     }
150/// }
151///
152/// struct FibUntil(u32);
153///
154/// impl Iterable for FibUntil {
155///     type Item = u32;
156///
157///     type Iter = FibUntilIter;
158///
159///     fn iter(&self) -> Self::Iter {
160///         FibUntilIter { curr: 0, next: 1, until: self.0 }
161///     }
162/// }
163///
164/// let fib = FibUntil(10); // Iterable
165///
166/// assert_eq!(fib.iter().count(), 7);
167/// assert_eq!(fib.iter().max(), Some(8));
168/// assert_eq!(fib.iter().collect::<Vec<_>>(), [0, 1, 1, 2, 3, 5, 8]);
169/// ```
170pub trait Iterable {
171    /// Type of the item that the iterators created by the [`iter`] method yields.
172    ///
173    /// [`iter`]: crate::Iterable::iter
174    type Item;
175
176    /// Type of the iterator created by the [`iter`] method.
177    ///
178    /// [`iter`]: crate::Iterable::iter
179    type Iter: Iterator<Item = Self::Item>;
180
181    /// Creates a new iterator from this iterable yielding elements of type `Iterable::Item`.
182    fn iter(&self) -> Self::Iter;
183
184    // provided
185
186    /// Takes two iterables and creates a new iterable over both in sequence.
187    ///
188    /// In other words, it links two iterators together, in a chain.
189    ///
190    /// [`once`] is commonly used to adapt a single value into a chain of other kinds of iteration.
191    ///
192    /// [`once`]: crate::once
193    ///
194    /// # Examples
195    ///
196    /// ```
197    /// use orx_iterable::*;
198    ///
199    /// let a = vec!['a', 'b'];
200    /// let b = ['c', 'd', 'e'];
201    ///
202    /// let it = a.chained(&b).copied();
203    /// assert_eq!(it.iter().count(), 5);
204    /// assert_eq!(it.iter().collect::<Vec<_>>(), vec!['a', 'b', 'c', 'd', 'e']);
205    /// ```
206    fn chained<I>(self, other: I) -> Chained<Self, I>
207    where
208        Self: Sized,
209        I: Iterable<Item = Self::Item>,
210    {
211        Chained {
212            it1: self,
213            it2: other,
214        }
215    }
216
217    /// Creates an iterable, iterators of which clone all of its elements.
218    ///
219    /// This is useful when you have an iterable over &T, but you need an iterable over T.
220    ///
221    /// # Examples
222    ///
223    /// ```
224    /// use orx_iterable::*;
225    ///
226    /// fn count_and_sum(data: impl Iterable<Item = i32>) -> (usize, i32) {
227    ///     (data.iter().count(), data.iter().sum())
228    /// }
229    ///
230    /// let a = vec![1, 3, 7, 15];
231    ///
232    /// assert_eq!((4, 26), count_and_sum(a.cloned()));
233    ///
234    /// assert_eq!((3, 11), count_and_sum(a.filtered(|x| **x < 10).cloned()));
235    /// ```
236    fn cloned<'a, T>(self) -> Cloned<'a, T, Self>
237    where
238        Self: Sized + Iterable<Item = &'a T>,
239        T: Clone,
240    {
241        Cloned { it: self }
242    }
243
244    /// Creates an iterable, iterators of which copy all of its elements.
245    ///
246    /// This is useful when you have an iterable over &T, but you need an iterable over T.
247    ///
248    /// # Examples
249    ///
250    /// ```
251    /// use orx_iterable::*;
252    ///
253    /// fn count_and_sum(data: impl Iterable<Item = i32>) -> (usize, i32) {
254    ///     (data.iter().count(), data.iter().sum())
255    /// }
256    ///
257    /// let a = vec![1, 3, 7, 15];
258    ///
259    /// assert_eq!((4, 26), count_and_sum(a.copied()));
260    ///
261    /// assert_eq!((3, 11), count_and_sum(a.filtered(|x| **x < 10).copied()));
262    /// ```
263    fn copied<'a, T>(self) -> Copied<'a, T, Self>
264    where
265        Self: Sized + Iterable<Item = &'a T>,
266        T: Copy,
267    {
268        Copied { it: self }
269    }
270
271    /// Creates an iterable which gives the current iteration count as well as the next value.
272    ///
273    /// The iterators created by enumerated iterable yields pairs `(i, val)`,
274    /// where `i` is the current index of iteration and `val` is the value returned by the iterator.
275    ///
276    /// # Examples
277    ///
278    /// ```
279    /// use orx_iterable::*;
280    ///
281    /// let a = ['a', 'b', 'c'];
282    /// let it = a.enumerated();
283    ///
284    /// assert_eq!(it.iter().count(), 3);
285    /// assert_eq!(it.iter().collect::<Vec<_>>(), vec![(0, &'a'), (1, &'b'), (2, &'c')]);
286    /// ```
287    fn enumerated(self) -> Enumerated<Self>
288    where
289        Self: Sized,
290    {
291        Enumerated { it: self }
292    }
293
294    /// Creates an iterable that both filters and maps.
295    ///
296    /// Iterators of the returned iterable yields only the values for which the supplied closure returns `Some(value)`.
297    ///
298    /// `filter_mapped` can be used to make chains of `filtered` and `mapped` more concise.
299    /// The example below shows how a `mapped().filtered().mapped()` can be shortened to a single call
300    /// to `filter_mapped`.
301    ///
302    /// # Examples
303    ///
304    /// ```
305    /// use orx_iterable::*;
306    ///
307    /// let a = ["1", "two", "NaN", "four", "5"];
308    ///
309    /// let it = a.filter_mapped(|s| s.parse::<u32>().ok());
310    ///
311    /// assert_eq!(it.iter().count(), 2);
312    /// assert_eq!(it.iter().collect::<Vec<_>>(), vec![1, 5]);
313    /// ```
314    fn filter_mapped<M, U>(self, filter_map: M) -> FilterMapped<Self, M, U>
315    where
316        Self: Sized,
317        M: Fn(Self::Item) -> Option<U> + Copy,
318    {
319        FilterMapped {
320            it: self,
321            filter_map,
322        }
323    }
324
325    /// Creates an iterable which uses a closure to determine if an element should be yielded.
326    ///
327    /// Given an element the closure must return true or false. Iterators of the returned iterable
328    /// will yield only the elements for which the closure returns true.
329    ///
330    /// # Examples
331    ///
332    /// ```
333    /// use orx_iterable::*;
334    ///
335    /// let a = [0i32, 1, 2];
336    ///
337    /// let it = a.filtered(|x| x.is_positive());
338    ///
339    /// assert_eq!(it.iter().count(), 2);
340    /// assert_eq!(it.iter().collect::<Vec<_>>(), [&1, &2]);
341    /// ```
342    fn filtered<P>(self, filter: P) -> Filtered<Self, P>
343    where
344        Self: Sized,
345        P: Fn(&Self::Item) -> bool + Copy,
346    {
347        Filtered { it: self, filter }
348    }
349
350    /// Creates an iterable that works like map, but flattens nested structure.
351    ///
352    /// You can think of `flat_mapped(f)` as the semantic equivalent of mapping,
353    /// and then flattening as in `mapped(f).flattened()`.
354    ///
355    /// Another way of thinking about `flat_mapped()`:
356    ///
357    /// * `mapped`’s closure returns one item for each element, and
358    /// * `flat_map()`’s closure returns an iterator for each element.
359    ///
360    /// # Examples
361    ///
362    /// ```
363    /// use orx_iterable::*;
364    ///
365    /// let words = ["al", "p", "ha"];
366    ///
367    /// let it = words.flat_mapped(|s| s.chars());
368    ///
369    /// assert_eq!(it.iter().count(), 5);
370    /// assert_eq!(it.iter().collect::<String>().as_str(), "alpha");
371    /// ```
372    fn flat_mapped<M, U>(self, flat_map: M) -> FlatMapped<Self, M, U>
373    where
374        Self: Sized,
375        U: IntoIterator,
376        M: Fn(Self::Item) -> U + Copy,
377    {
378        FlatMapped { it: self, flat_map }
379    }
380
381    /// Creates an iterable that flattens nested structure.
382    ///
383    /// This is useful when you have an iterable of iterators or an iterable of things that can be
384    /// turned into iterators and you want to remove one level of indirection.
385    ///
386    /// # Examples
387    ///
388    /// ```
389    /// use orx_iterable::*;
390    ///
391    /// let data = vec![vec![1, 2, 3, 4], vec![5, 6]];
392    ///
393    /// let it = data.flattened();
394    ///
395    /// assert_eq!(it.iter().count(), 6);
396    /// assert_eq!(it.iter().sum::<u32>(), 21);
397    /// ```
398    fn flattened(self) -> Flattened<Self>
399    where
400        Self: Sized,
401        Self::Item: IntoIterator,
402    {
403        Flattened { it: self }
404    }
405
406    /// Creates an iterable which ends after the first `None`.
407    ///
408    /// After an iterator returns `None`, future calls may or may not yield `Some(T)` again.
409    /// fuse() adapts an iterator, ensuring that after a `None` is given, it will always return `None` forever.
410    ///
411    /// Note that the Fuse wrapper is a no-op on iterators that implement the FusedIterator trait.
412    /// fuse() may therefore behave incorrectly if the FusedIterator trait is improperly implemented.
413    fn fused(self) -> Fused<Self>
414    where
415        Self: Sized,
416    {
417        Fused { it: self }
418    }
419
420    /// Creates an iterable that both yields elements based on a predicate and maps.
421    ///
422    /// `map_while()` takes a closure as an argument. It will call this closure on each element
423    /// of the iterator, and yield elements while it returns `Some(_)`.
424    ///
425    /// # Examples
426    ///
427    /// ```
428    /// use orx_iterable::*;
429    ///
430    /// let a = [0, 1, 2, -3, 4, 5, -6];
431    ///
432    /// let it = a.mapped_while(|x| u32::try_from(*x).ok());
433    ///
434    /// assert_eq!(it.iter().count(), 3);
435    /// assert_eq!(it.iter().collect::<Vec<_>>(), [0, 1, 2]);
436    /// ```
437    fn mapped_while<M, U>(self, map_while: M) -> MappedWhile<Self, M, U>
438    where
439        Self: Sized,
440        M: Fn(Self::Item) -> Option<U> + Copy,
441    {
442        MappedWhile {
443            it: self,
444            map_while,
445        }
446    }
447
448    /// Takes a closure and creates an iterable which calls that closure on each element.
449    ///
450    /// map() transforms one iterator into another, by means of its argument `map`.
451    /// It produces a new iterable, iterators of which calls this closure on each element of
452    /// the original iterable.
453    ///
454    /// # Example
455    ///
456    /// ```
457    /// use orx_iterable::*;
458    ///
459    /// let a = [1, 3, 6];
460    ///
461    /// let it = a.mapped(|x| 2 * x);
462    ///
463    /// assert_eq!(it.iter().sum::<i32>(), 20);
464    /// assert_eq!(it.iter().collect::<Vec<_>>(), [2, 6, 12]);
465    /// ```
466    fn mapped<M, U>(self, map: M) -> Mapped<Self, M, U>
467    where
468        Self: Sized,
469        M: Fn(Self::Item) -> U + Copy,
470    {
471        Mapped { it: self, map }
472    }
473
474    /// Creates an iterable iterators of which reverses the traversal direction.
475    ///
476    /// This is only possible if the iterable's iterator type has an end,
477    /// so `reversed()` only works when `Iterable::Iter` is a `DoubleEndedIterator`.
478    ///
479    /// # Example
480    ///
481    /// ```
482    /// use orx_iterable::*;
483    ///
484    /// let a = [1, 2, 3];
485    ///
486    /// let it = a.reversed();
487    /// assert_eq!(it.iter().collect::<Vec<_>>(), [&3, &2, &1]);
488    ///
489    /// let it = it.reversed();
490    /// assert_eq!(it.iter().collect::<Vec<_>>(), [&1, &2, &3]);
491    /// ```
492    fn reversed(self) -> Reversed<Self>
493    where
494        Self: Sized,
495        Self::Iter: DoubleEndedIterator,
496    {
497        Reversed { it: self }
498    }
499
500    /// Creates an iterable, iterators of which skip the first `n` elements.
501    ///
502    /// Created iterators skip elements until n elements are skipped or the end of the iterator
503    /// is reached (whichever happens first).
504    /// After that, all the remaining elements are yielded. In particular, if the original iterator
505    /// is too short, then the returned iterator is empty.
506    ///
507    /// # Examples
508    ///
509    /// ```
510    /// use orx_iterable::*;
511    ///
512    /// let a = [1, 2, 3];
513    ///
514    /// let it = a.skipped(2);
515    ///
516    /// assert_eq!(it.iter().count(), 1);
517    /// assert_eq!(it.iter().next(), Some(&3));
518    /// ```
519    fn skipped(self, n: usize) -> Skipped<Self>
520    where
521        Self: Sized,
522    {
523        Skipped { it: self, n }
524    }
525
526    /// Creates an iterable, iterators of which skip elements based on a predicate.
527    ///
528    /// `skipped_while()` takes a closure as an argument. It will call this closure on each element
529    /// of the iterator, and ignore elements until it returns false.
530    ///
531    /// After false is returned, `skip_while`’s job is over, and the rest of the elements are yielded.
532    ///
533    /// # Examples
534    ///
535    /// ```
536    /// use orx_iterable::*;
537    ///
538    /// let a = [-1i32, 0, 1];
539    ///
540    /// let it = a.skipped_while(|x| x.is_negative());
541    ///
542    /// assert_eq!(it.iter().collect::<Vec<_>>(), [&0, &1]);
543    /// ```
544    fn skipped_while<P>(self, skip_while: P) -> SkippedWhile<Self, P>
545    where
546        Self: Sized,
547        P: Fn(&Self::Item) -> bool + Copy,
548    {
549        SkippedWhile {
550            it: self,
551            skip_while,
552        }
553    }
554
555    /// Creates an iterable starting at the same point, but stepping by the given amount at each iteration.
556    ///
557    /// The first element of the iterator will always be returned, regardless of the step given.
558    ///
559    /// # Examples
560    ///
561    /// ```
562    /// use orx_iterable::*;
563    ///
564    /// let a = [0, 1, 2, 3, 4, 5];
565    ///
566    /// let it = a.stepped_by(2);
567    ///
568    /// assert_eq!(it.iter().collect::<Vec<_>>(), [&0, &2, &4]);
569    /// ```
570    fn stepped_by(self, step: usize) -> SteppedBy<Self>
571    where
572        Self: Sized,
573    {
574        SteppedBy { it: self, step }
575    }
576
577    /// Creates an iterable whose iterators yield the first `n` elements, or fewer if the underlying iterator ends sooner.
578    ///
579    /// # Examples
580    ///
581    /// ```
582    /// use orx_iterable::*;
583    ///
584    /// let a = [1, 2, 3];
585    ///
586    /// let it = a.taken(2);
587    ///
588    /// assert_eq!(it.iter().collect::<Vec<_>>(), [&1, &2]);
589    /// ```
590    fn taken(self, n: usize) -> Taken<Self>
591    where
592        Self: Sized,
593    {
594        Taken { it: self, n }
595    }
596
597    /// Creates an iterable, iterators of which yield elements based on a predicate.
598    ///
599    /// `taken_while()` takes a closure as an argument.
600    /// It will call this closure on each element of the iterator, and yield elements while it returns true.
601    ///
602    /// After false is returned, the rest of the elements are ignored.
603    ///
604    /// # Examples
605    ///
606    /// ```
607    /// use orx_iterable::*;
608    ///
609    /// let a = [-1i32, 0, 1];
610    ///
611    /// let it = a.taken_while(|x| x.is_negative());
612    ///
613    /// assert_eq!(it.iter().count(), 1);
614    /// assert_eq!(it.iter().next(), Some(&-1));
615    /// ```
616    fn taken_while<P>(self, take_while: P) -> TakenWhile<Self, P>
617    where
618        Self: Sized,
619        P: Fn(&Self::Item) -> bool + Copy,
620    {
621        TakenWhile {
622            it: self,
623            take_while,
624        }
625    }
626
627    /// ‘Zips up’ two iterables into a single iterable of pairs.
628    ///
629    /// The zipped iterable creates zipped iterators.
630    ///
631    /// If either iterator returns None, next from the zipped iterator will return None.
632    /// If the zipped iterator has no more elements to return then each further attempt to advance it will first try to
633    /// advance the first iterator at most one time and if it still yielded an item try to advance the second iterator
634    /// at most one time.
635    ///
636    /// # Examples
637    ///
638    /// ```
639    /// use orx_iterable::*;
640    ///
641    /// let a1 = [1, 2, 3];
642    /// let b1 = [4, 5, 6, 7];
643    ///
644    /// let it = a1.zipped(&b1);
645    ///
646    /// assert_eq!(it.iter().count(), 3);
647    /// assert_eq!(it.iter().collect::<Vec<_>>(), [(&1, &4), (&2, &5), (&3, &6)]);
648    /// ```
649    fn zipped<I>(self, other: I) -> Zipped<Self, I>
650    where
651        Self: Sized,
652        I: Iterable,
653    {
654        Zipped {
655            it1: self,
656            it2: other,
657        }
658    }
659}
660
661// impl
662
663impl<'a, X> Iterable for &'a X
664where
665    &'a X: IntoIterator,
666{
667    type Item = <&'a X as IntoIterator>::Item;
668
669    type Iter = <&'a X as IntoIterator>::IntoIter;
670
671    fn iter(&self) -> Self::Iter {
672        self.into_iter()
673    }
674}
675
676impl<'a, X> Iterable for &'a [X] {
677    type Item = &'a X;
678
679    type Iter = core::slice::Iter<'a, X>;
680
681    fn iter(&self) -> Self::Iter {
682        <[X]>::iter(self)
683    }
684}