1use crate::fmt;
2use crate::iter::{FusedIterator, TrustedLen};
34/// Creates an iterator that lazily generates a value exactly once by invoking
5/// the provided closure.
6///
7/// This is commonly used to adapt a single value coroutine into a [`chain()`] of
8/// other kinds of iteration. Maybe you have an iterator that covers almost
9/// everything, but you need an extra special case. Maybe you have a function
10/// which works on iterators, but you only need to process one value.
11///
12/// Unlike [`once()`], this function will lazily generate the value on request.
13///
14/// [`chain()`]: Iterator::chain
15/// [`once()`]: crate::iter::once
16///
17/// # Examples
18///
19/// Basic usage:
20///
21/// ```
22/// use std::iter;
23///
24/// // one is the loneliest number
25/// let mut one = iter::once_with(|| 1);
26///
27/// assert_eq!(Some(1), one.next());
28///
29/// // just one, that's all we get
30/// assert_eq!(None, one.next());
31/// ```
32///
33/// Chaining together with another iterator. Let's say that we want to iterate
34/// over each file of the `.foo` directory, but also a configuration file,
35/// `.foorc`:
36///
37/// ```no_run
38/// use std::iter;
39/// use std::fs;
40/// use std::path::PathBuf;
41///
42/// let dirs = fs::read_dir(".foo").unwrap();
43///
44/// // we need to convert from an iterator of DirEntry-s to an iterator of
45/// // PathBufs, so we use map
46/// let dirs = dirs.map(|file| file.unwrap().path());
47///
48/// // now, our iterator just for our config file
49/// let config = iter::once_with(|| PathBuf::from(".foorc"));
50///
51/// // chain the two iterators together into one big iterator
52/// let files = dirs.chain(config);
53///
54/// // this will give us all of the files in .foo as well as .foorc
55/// for f in files {
56/// println!("{f:?}");
57/// }
58/// ```
59#[inline]
60#[stable(feature = "iter_once_with", since = "1.43.0")]
61pub fn once_with<A, F: FnOnce() -> A>(make: F) -> OnceWith<F> {
62OnceWith { make: Some(make) }
63}
6465/// An iterator that yields a single element of type `A` by
66/// applying the provided closure `F: FnOnce() -> A`.
67///
68/// This `struct` is created by the [`once_with()`] function.
69/// See its documentation for more.
70#[derive(#[automatically_derived]
#[stable(feature = "iter_once_with", since = "1.43.0")]
impl<F: crate::clone::Clone> crate::clone::Clone for OnceWith<F> {
#[inline]
fn clone(&self) -> OnceWith<F> {
OnceWith { make: crate::clone::Clone::clone(&self.make) }
}
}Clone)]
71#[stable(feature = "iter_once_with", since = "1.43.0")]
72pub struct OnceWith<F> {
73 make: Option<F>,
74}
7576#[stable(feature = "iter_once_with_debug", since = "1.68.0")]
77impl<F> fmt::Debugfor OnceWith<F> {
78fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79if self.make.is_some() {
80f.write_str("OnceWith(Some(_))")
81 } else {
82f.write_str("OnceWith(None)")
83 }
84 }
85}
8687#[stable(feature = "iter_once_with", since = "1.43.0")]
88impl<A, F: FnOnce() -> A> Iteratorfor OnceWith<F> {
89type Item = A;
9091#[inline]
92fn next(&mut self) -> Option<A> {
93let f = self.make.take()?;
94Some(f())
95 }
9697#[inline]
98fn size_hint(&self) -> (usize, Option<usize>) {
99self.make.iter().size_hint()
100 }
101}
102103#[stable(feature = "iter_once_with", since = "1.43.0")]
104impl<A, F: FnOnce() -> A> DoubleEndedIteratorfor OnceWith<F> {
105fn next_back(&mut self) -> Option<A> {
106self.next()
107 }
108}
109110#[stable(feature = "iter_once_with", since = "1.43.0")]
111impl<A, F: FnOnce() -> A> ExactSizeIteratorfor OnceWith<F> {
112fn len(&self) -> usize {
113self.make.iter().len()
114 }
115}
116117#[stable(feature = "iter_once_with", since = "1.43.0")]
118impl<A, F: FnOnce() -> A> FusedIteratorfor OnceWith<F> {}
119120#[stable(feature = "iter_once_with", since = "1.43.0")]
121unsafe impl<A, F: FnOnce() -> A> TrustedLenfor OnceWith<F> {}