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
//! This is like [cycle](std::iter::Cycle) but after an iterator end the last element is returned
//! infinitely.

use std::iter::Fuse;

/// Extension trait for Iterator that allow use `FuseLast` in chain-like manner.
pub trait IteratorExt: Iterator {
    /// Creates an iterator that will be fused on last element forever.
    ///
    /// After an iterator returns `None`, future calls may or may not yield `Some(T)` again.
    /// `fuse_last()` adapts an iterator, ensuring that after a `None` is given from `self` iter, it will forever return last received element from inner iterator.
    ///
    /// # Examples
    /// ```
    /// use futures_test_sink::fuse_last::IteratorExt;
    ///
    /// let iter = vec![1, 2].into_iter();
    /// let mut fuse_last_iter = iter.fuse_last();
    /// assert_eq!(Some(1), fuse_last_iter.next());
    /// assert_eq!(Some(2), fuse_last_iter.next());
    /// assert_eq!(Some(2), fuse_last_iter.next());
    /// ```
    ///
    /// The only way to return `None` is empty inner iterator.
    /// ```
    /// use futures_test_sink::fuse_last::IteratorExt;
    /// use std::iter::empty;
    ///
    /// let mut fuse_last_iter = empty::<()>().fuse_last();
    /// assert_eq!(None, fuse_last_iter.next());
    /// assert_eq!(None, fuse_last_iter.next());
    /// ```
    fn fuse_last(self) -> FuseLast<Self, Self::Item>
    where
        Self: Sized,
        Self::Item: Clone;
}

impl<T: Iterator> IteratorExt for T {
    fn fuse_last(self) -> FuseLast<Self, Self::Item>
    where
        Self: Sized,
        Self::Item: Clone,
    {
        FuseLast::new(self)
    }
}

/// `FuseLast` forever return last item after exhaust inner iterator.
pub struct FuseLast<I, Item> {
    iter: Fuse<I>,
    last_item: Option<Item>,
}

impl<I> FuseLast<I, I::Item>
where
    I: Iterator,
    I::Item: Clone,
{
    fn new(iter: I) -> Self {
        Self {
            iter: iter.fuse(),
            last_item: None,
        }
    }
}

impl<I> Iterator for FuseLast<I, I::Item>
where
    I: Iterator,
    I::Item: Clone,
{
    type Item = I::Item;
    fn next(&mut self) -> Option<Self::Item> {
        match self.iter.next() {
            Some(v) => {
                self.last_item = Some(v.clone());
                Some(v)
            }
            None => self.last_item.clone(),
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn compile() {
        let iter = vec![1, 2].into_iter();
        let mut fuse_last_iter = iter.fuse_last();
        assert_eq!(Some(1), fuse_last_iter.next());
        assert_eq!(Some(2), fuse_last_iter.next());
        assert_eq!(Some(2), fuse_last_iter.next());
    }
}