core/iter/sources/
once_with.rs

1use crate::fmt;
2use crate::iter::{FusedIterator, TrustedLen};
3
4/// 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> {
62    OnceWith { make: Some(make) }
63}
64
65/// 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(Clone)]
71#[stable(feature = "iter_once_with", since = "1.43.0")]
72pub struct OnceWith<F> {
73    make: Option<F>,
74}
75
76#[stable(feature = "iter_once_with_debug", since = "1.68.0")]
77impl<F> fmt::Debug for OnceWith<F> {
78    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79        if self.make.is_some() {
80            f.write_str("OnceWith(Some(_))")
81        } else {
82            f.write_str("OnceWith(None)")
83        }
84    }
85}
86
87#[stable(feature = "iter_once_with", since = "1.43.0")]
88impl<A, F: FnOnce() -> A> Iterator for OnceWith<F> {
89    type Item = A;
90
91    #[inline]
92    fn next(&mut self) -> Option<A> {
93        let f = self.make.take()?;
94        Some(f())
95    }
96
97    #[inline]
98    fn size_hint(&self) -> (usize, Option<usize>) {
99        self.make.iter().size_hint()
100    }
101}
102
103#[stable(feature = "iter_once_with", since = "1.43.0")]
104impl<A, F: FnOnce() -> A> DoubleEndedIterator for OnceWith<F> {
105    fn next_back(&mut self) -> Option<A> {
106        self.next()
107    }
108}
109
110#[stable(feature = "iter_once_with", since = "1.43.0")]
111impl<A, F: FnOnce() -> A> ExactSizeIterator for OnceWith<F> {
112    fn len(&self) -> usize {
113        self.make.iter().len()
114    }
115}
116
117#[stable(feature = "iter_once_with", since = "1.43.0")]
118impl<A, F: FnOnce() -> A> FusedIterator for OnceWith<F> {}
119
120#[stable(feature = "iter_once_with", since = "1.43.0")]
121unsafe impl<A, F: FnOnce() -> A> TrustedLen for OnceWith<F> {}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy