Skip to content

Commit 857288e

Browse files
committed
Add fn once_with and OnceWith
1 parent bcf58d0 commit 857288e

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ pub use sources::{convert, Convert};
5050
pub use sources::{convert_ref, ConvertRef};
5151
pub use sources::{empty, Empty};
5252
pub use sources::{once, Once};
53+
pub use sources::{once_with, OnceWith};
5354

5455
/// An interface for dealing with streaming iterators.
5556
pub trait StreamingIterator {

src/sources.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ pub fn once<T>(item: T) -> Once<T> {
5151
}
5252
}
5353

54+
/// Creates an iterator that returns exactly one item from a function call.
55+
#[inline]
56+
pub fn once_with<T, F: FnOnce() -> T>(gen: F) -> OnceWith<T, F> {
57+
OnceWith {
58+
gen: Some(gen),
59+
item: None,
60+
}
61+
}
62+
5463
/// A streaming iterator which yields elements from a normal, non-streaming, iterator.
5564
#[derive(Clone, Debug)]
5665
pub struct Convert<I>
@@ -247,3 +256,40 @@ impl<T> DoubleEndedStreamingIterator for Once<T> {
247256
self.advance();
248257
}
249258
}
259+
260+
/// A simple iterator that returns exactly one item from a function call.
261+
#[derive(Clone, Debug)]
262+
pub struct OnceWith<T, F> {
263+
gen: Option<F>,
264+
item: Option<T>,
265+
}
266+
267+
impl<T, F: FnOnce() -> T> StreamingIterator for OnceWith<T, F> {
268+
type Item = T;
269+
270+
#[inline]
271+
fn advance(&mut self) {
272+
self.item = match self.gen.take() {
273+
Some(gen) => Some(gen()),
274+
None => None,
275+
};
276+
}
277+
278+
#[inline]
279+
fn get(&self) -> Option<&Self::Item> {
280+
self.item.as_ref()
281+
}
282+
283+
#[inline]
284+
fn size_hint(&self) -> (usize, Option<usize>) {
285+
let len = self.gen.is_some() as usize;
286+
(len, Some(len))
287+
}
288+
}
289+
290+
impl<T, F: FnOnce() -> T> DoubleEndedStreamingIterator for OnceWith<T, F> {
291+
#[inline]
292+
fn advance_back(&mut self) {
293+
self.advance();
294+
}
295+
}

0 commit comments

Comments
 (0)