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