use crate::fmt; use crate::iter::FusedIterator; /// Creates an iterator which, starting from an initial item, /// computes each successive item from the preceding one. /// /// This iterator stores an optional item (`Option`) and a successor closure (`impl FnMut(&T) -> Option`). /// Its `next` method returns the stored optional item and /// if it is `Some(val)` calls the stored closure on `&val` to compute and store its successor. /// The iterator will apply the closure successively to the stored option's value until the option is `None`. /// This also means that once the stored option is `None` it will remain `None`, /// as the closure will not be called again, so the created iterator is a [`FusedIterator`]. /// The iterator's items will be the initial item and all of its successors as calculated by the successor closure. /// /// ``` /// use std::iter::successors; /// /// let powers_of_10 = successors(Some(1_u16), |n| n.checked_mul(10)); /// assert_eq!(powers_of_10.collect::>(), &[1, 10, 100, 1_000, 10_000]); /// ``` #[stable(feature = "iter_successors", since = "1.34.0")] pub fn successors(first: Option, succ: F) -> Successors where F: FnMut(&T) -> Option, { // If this function returned `impl Iterator` // it could be based on `from_fn` and not need a dedicated type. // However having a named `Successors` type allows it to be `Clone` when `T` and `F` are. Successors { next: first, succ } } /// An iterator which, starting from an initial item, /// computes each successive item from the preceding one. /// /// This `struct` is created by the [`iter::successors()`] function. /// See its documentation for more. /// /// [`iter::successors()`]: successors #[derive(Clone)] #[stable(feature = "iter_successors", since = "1.34.0")] pub struct Successors { next: Option, succ: F, } #[stable(feature = "iter_successors", since = "1.34.0")] impl Iterator for Successors where F: FnMut(&T) -> Option, { type Item = T; #[inline] fn next(&mut self) -> Option { let item = self.next.take()?; self.next = (self.succ)(&item); Some(item) } #[inline] fn size_hint(&self) -> (usize, Option) { if self.next.is_some() { (1, None) } else { (0, Some(0)) } } } #[stable(feature = "iter_successors", since = "1.34.0")] impl FusedIterator for Successors where F: FnMut(&T) -> Option {} #[stable(feature = "iter_successors", since = "1.34.0")] impl fmt::Debug for Successors { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Successors").field("next", &self.next).finish() } }