1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// 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.

pub struct Unfold<F, S> {
    f: F,
    value: S,
}

impl<F, S, A> Iterator for Unfold<F, S>
where
    F: Fn(&S) -> Option<(A, S)>,
{
    type Item = A;

    fn next(&mut self) -> Option<Self::Item> {
        match (self.f)(&self.value) {
            None => None,
            Some((next, value)) => {
                self.value = value;
                Some(next)
            }
        }
    }
}

pub struct UnfoldMut<F, S> {
    f: F,
    value: S,
}

impl<F, S, A> Iterator for UnfoldMut<F, S>
where
    F: Fn(&mut S) -> Option<A>,
{
    type Item = A;

    fn next(&mut self) -> Option<Self::Item> {
        (self.f)(&mut self.value)
    }
}

/// Create an iterator of values using a function to update a 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;
/// # use im::iter::unfold;
/// # use im::vector::Vector;
/// # use std::iter::FromIterator;
/// # fn main() {
/// // 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
#[must_use]
pub fn unfold<F, S, A>(value: S, f: F) -> Unfold<F, S>
where
    F: Fn(&S) -> Option<(A, S)>,
{
    Unfold { f, value }
}

/// Create an iterator of values using a function to mutate a state
/// value.
///
/// The function is called with a mutable reference to the current
/// state as its argument, and should return an
/// [`Option`][std::option::Option] of the next value to yield from
/// the iterator, updating the state as necessary. If the function
/// returns [`None`][std::option::Option::None], the iterator ends.
///
/// This differs from [`unfold`][unfold] in that your update functions
/// will probably be less elegant, but it's easier to deal with state
/// that isn't efficiently cloneable.
///
/// # Examples
/// ```
/// # #[macro_use] extern crate im;
/// # use im::iter::unfold_mut;
/// # use im::vector::Vector;
/// # use std::iter::FromIterator;
/// # fn main() {
/// // Create an infinite stream of numbers, starting at 0.
/// let mut it = unfold_mut(0, |i| {
///   let next = *i;
///   *i += 1;
///   Some(next)
/// });
///
/// // 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
/// [unfold]: ./fn.unfold.html
#[must_use]
pub fn unfold_mut<F, S, A>(value: S, f: F) -> UnfoldMut<F, S>
where
    F: Fn(&mut S) -> Option<A>,
{
    UnfoldMut { f, value }
}