core/iter/sources/from_fn.rs
1#[cfg(not(feature = "ferrocene_certified"))]
2use crate::fmt;
3
4/// Creates an iterator with the provided closure
5/// `F: FnMut() -> Option<T>` as its [`next`](Iterator::next) method.
6///
7/// The iterator will yield the `T`s returned from the closure.
8///
9/// This allows creating a custom iterator with any behavior
10/// without using the more verbose syntax of creating a dedicated type
11/// and implementing the [`Iterator`] trait for it.
12///
13/// Note that the `FromFn` iterator doesn’t make assumptions about the behavior of the closure,
14/// and therefore conservatively does not implement [`FusedIterator`],
15/// or override [`Iterator::size_hint()`] from its default `(0, None)`.
16///
17/// The closure can use captures and its environment to track state across iterations. Depending on
18/// how the iterator is used, this may require specifying the [`move`] keyword on the closure.
19///
20/// [`move`]: ../../std/keyword.move.html
21/// [`FusedIterator`]: crate::iter::FusedIterator
22///
23/// # Examples
24///
25/// Let’s re-implement the counter iterator from [module-level documentation]:
26///
27/// [module-level documentation]: crate::iter
28///
29/// ```
30/// let mut count = 0;
31/// let counter = std::iter::from_fn(move || {
32/// // Increment our count. This is why we started at zero.
33/// count += 1;
34///
35/// // Check to see if we've finished counting or not.
36/// if count < 6 {
37/// Some(count)
38/// } else {
39/// None
40/// }
41/// });
42/// assert_eq!(counter.collect::<Vec<_>>(), &[1, 2, 3, 4, 5]);
43/// ```
44#[inline]
45#[stable(feature = "iter_from_fn", since = "1.34.0")]
46pub fn from_fn<T, F>(f: F) -> FromFn<F>
47where
48 F: FnMut() -> Option<T>,
49{
50 FromFn(f)
51}
52
53/// An iterator where each iteration calls the provided closure `F: FnMut() -> Option<T>`.
54///
55/// This `struct` is created by the [`iter::from_fn()`] function.
56/// See its documentation for more.
57///
58/// [`iter::from_fn()`]: from_fn
59#[derive(Clone)]
60#[stable(feature = "iter_from_fn", since = "1.34.0")]
61pub struct FromFn<F>(F);
62
63#[stable(feature = "iter_from_fn", since = "1.34.0")]
64impl<T, F> Iterator for FromFn<F>
65where
66 F: FnMut() -> Option<T>,
67{
68 type Item = T;
69
70 #[inline]
71 fn next(&mut self) -> Option<Self::Item> {
72 (self.0)()
73 }
74}
75
76#[cfg(not(feature = "ferrocene_certified"))]
77#[stable(feature = "iter_from_fn", since = "1.34.0")]
78impl<F> fmt::Debug for FromFn<F> {
79 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80 f.debug_struct("FromFn").finish()
81 }
82}