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
use alloc::string::String;
use alloc::vec::Vec;

use super::Rope;

pub struct Chunks<'a> {
    stack: Vec<&'a Rope>,
    current: Option<&'a String>,
}

unsafe impl<'a> Sync for Chunks<'a> {}
unsafe impl<'a> Send for Chunks<'a> {}

impl<'a> From<&'a Rope> for Chunks<'a> {
    #[inline]
    fn from(rope: &'a Rope) -> Self {
        let mut iter = Chunks {
            stack: Vec::new(),
            current: None,
        };
        iter.load_stack(rope);
        iter
    }
}

impl<'a> Chunks<'a> {
    #[inline]
    fn load_stack(&mut self, mut rope: &'a Rope) {
        loop {
            match rope {
                &Rope::Node(_, ref left, ref right) => {
                    self.stack.push(right);
                    rope = left;
                }
                &Rope::Leaf(ref string) => {
                    self.current = Some(string);
                    break;
                }
            }
        }
    }
}

impl<'a> Iterator for Chunks<'a> {
    type Item = &'a String;

    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        let result = self.current.take();

        if let Some(rope) = self.stack.pop() {
            self.load_stack(rope);
        }

        result
    }
}