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