diff options
Diffstat (limited to 'vendor/im-rc/src/iter.rs')
-rw-r--r-- | vendor/im-rc/src/iter.rs | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/vendor/im-rc/src/iter.rs b/vendor/im-rc/src/iter.rs new file mode 100644 index 000000000..2327b8dd5 --- /dev/null +++ b/vendor/im-rc/src/iter.rs @@ -0,0 +1,42 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +//! Iterators over immutable data. + +/// Create an iterator of values using a function to update an owned state +/// value. +/// +/// The function is called with the current state as its argument, and should +/// return an [`Option`][std::option::Option] of a tuple of the next value to +/// yield from the iterator and the updated state. If the function returns +/// [`None`][std::option::Option::None], the iterator ends. +/// +/// # Examples +/// ``` +/// # #[macro_use] extern crate im_rc as im; +/// # use im::iter::unfold; +/// # use im::vector::Vector; +/// # use std::iter::FromIterator; +/// // Create an infinite stream of numbers, starting at 0. +/// let mut it = unfold(0, |i| Some((i, i + 1))); +/// +/// // Make a list out of its first five elements. +/// let numbers = Vector::from_iter(it.take(5)); +/// assert_eq!(numbers, vector![0, 1, 2, 3, 4]); +/// ``` +/// +/// [std::option::Option]: https://doc.rust-lang.org/std/option/enum.Option.html +/// [std::option::Option::None]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None +pub fn unfold<F, S, A>(value: S, f: F) -> impl Iterator<Item = A> +where + F: Fn(S) -> Option<(A, S)>, +{ + let mut value = Some(value); + std::iter::from_fn(move || { + f(value.take().unwrap()).map(|(next, state)| { + value = Some(state); + next + }) + }) +} |