core/iter/sources/
successors.rs

1use crate::fmt;
2use crate::iter::FusedIterator;
3
4/// Creates a new iterator where each successive item is computed based on the preceding one.
5///
6/// The iterator starts with the given first item (if any)
7/// and calls the given `FnMut(&T) -> Option<T>` closure to compute each item’s successor.
8/// The iterator will yield the `T`s returned from the closure.
9///
10/// ```
11/// use std::iter::successors;
12///
13/// let powers_of_10 = successors(Some(1_u16), |n| n.checked_mul(10));
14/// assert_eq!(powers_of_10.collect::<Vec<_>>(), &[1, 10, 100, 1_000, 10_000]);
15/// ```
16#[stable(feature = "iter_successors", since = "1.34.0")]
17pub fn successors<T, F>(first: Option<T>, succ: F) -> Successors<T, F>
18where
19    F: FnMut(&T) -> Option<T>,
20{
21    // If this function returned `impl Iterator<Item=T>`
22    // it could be based on `from_fn` and not need a dedicated type.
23    // However having a named `Successors<T, F>` type allows it to be `Clone` when `T` and `F` are.
24    Successors { next: first, succ }
25}
26
27/// A new iterator where each successive item is computed based on the preceding one.
28///
29/// This `struct` is created by the [`iter::successors()`] function.
30/// See its documentation for more.
31///
32/// [`iter::successors()`]: successors
33#[derive(Clone)]
34#[stable(feature = "iter_successors", since = "1.34.0")]
35pub struct Successors<T, F> {
36    next: Option<T>,
37    succ: F,
38}
39
40#[stable(feature = "iter_successors", since = "1.34.0")]
41impl<T, F> Iterator for Successors<T, F>
42where
43    F: FnMut(&T) -> Option<T>,
44{
45    type Item = T;
46
47    #[inline]
48    fn next(&mut self) -> Option<Self::Item> {
49        let item = self.next.take()?;
50        self.next = (self.succ)(&item);
51        Some(item)
52    }
53
54    #[inline]
55    fn size_hint(&self) -> (usize, Option<usize>) {
56        if self.next.is_some() { (1, None) } else { (0, Some(0)) }
57    }
58}
59
60#[stable(feature = "iter_successors", since = "1.34.0")]
61impl<T, F> FusedIterator for Successors<T, F> where F: FnMut(&T) -> Option<T> {}
62
63#[stable(feature = "iter_successors", since = "1.34.0")]
64impl<T: fmt::Debug, F> fmt::Debug for Successors<T, F> {
65    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66        f.debug_struct("Successors").field("next", &self.next).finish()
67    }
68}