Skip to main content

persistent_rope/
chunks.rs

1use alloc::{string::String, vec::Vec};
2
3use super::Rope;
4
5pub struct Chunks<'a> {
6  stack: Vec<&'a Rope>,
7  current: Option<&'a String>,
8}
9
10unsafe impl<'a> Sync for Chunks<'a> {}
11unsafe impl<'a> Send for Chunks<'a> {}
12
13impl<'a> From<&'a Rope> for Chunks<'a> {
14  #[inline]
15  fn from(rope: &'a Rope) -> Self {
16    let mut iter = Chunks {
17      stack: Vec::new(),
18      current: None,
19    };
20    iter.load_stack(rope);
21    iter
22  }
23}
24
25impl<'a> Chunks<'a> {
26  #[inline]
27  fn load_stack(&mut self, mut rope: &'a Rope) {
28    loop {
29      match rope {
30        &Rope::Node(_, ref left, ref right) => {
31          self.stack.push(right);
32          rope = left;
33        }
34        &Rope::Leaf(ref string) => {
35          self.current = Some(string);
36          break;
37        }
38      }
39    }
40  }
41}
42
43impl<'a> Iterator for Chunks<'a> {
44  type Item = &'a String;
45
46  #[inline]
47  fn next(&mut self) -> Option<Self::Item> {
48    let result = self.current.take();
49
50    if let Some(rope) = self.stack.pop() {
51      self.load_stack(rope);
52    }
53
54    result
55  }
56}