x_path/iter/
segments.rs

1use crate::inner::PathInner;
2
3#[derive(Debug)]
4pub struct Segments<'a> {
5    path: &'a PathInner,
6    pos: Option<usize>,
7    // start of the current str
8    start: usize,
9}
10
11impl<'a> Segments<'a> {
12    pub(crate) fn new(path: &'a PathInner) -> Self {
13        Self {
14            path,
15            pos: None,
16            start: 0,
17        }
18    }
19}
20
21impl<'a> Iterator for Segments<'a> {
22    type Item = &'a str;
23
24    fn next(&mut self) -> Option<Self::Item> {
25        let pos = match self.pos {
26            Some(pos) if pos + 1 >= self.path.lengths.len() => {
27                self.pos = None;
28                return None;
29            }
30            Some(pos) => pos + 1,
31            None if self.start == 0 => 0,
32            None => return None,
33        };
34        self.pos = Some(pos);
35
36        let start = self.start;
37        let end = start + self.path.lengths[pos] as usize;
38        self.start = end + 1;
39
40        // println!(">> {start}..{end} - {}", self.path.path.len());
41        Some(&self.path.path[start..end])
42    }
43
44    fn size_hint(&self) -> (usize, Option<usize>) {
45        let len = self.path.lengths.len();
46        let remaining = match self.pos {
47            Some(pos) => len - pos,
48            None => len,
49        };
50        (remaining, Some(remaining))
51    }
52}
53impl<'a> ExactSizeIterator for Segments<'a> {}
54
55impl<'a> DoubleEndedIterator for Segments<'a> {
56    fn next_back(&mut self) -> Option<Self::Item> {
57        let pos = match self.pos {
58            Some(pos) if pos > 0 => pos - 1,
59            Some(_) => return None,
60            None if self.start == 0 => {
61                self.pos = None;
62                return None;
63            }
64            None => self.len() - 1,
65        };
66
67        self.pos = Some(pos);
68
69        let end = self.start - 1;
70        let start = end - self.path.lengths[pos] as usize;
71        self.start = start;
72
73        // println!("<< {start}..{end} - {}", self.path.path.len());
74        Some(&self.path.path[start..end])
75    }
76}
77
78#[test]
79fn test_path_iter() {
80    let path = PathInner::new("var/some/paths").unwrap();
81
82    let mut iter = path.segments();
83    assert_eq!(iter.next(), Some("var"));
84    assert_eq!(iter.next(), Some("some"));
85    assert_eq!(iter.next(), Some("paths"));
86    assert_eq!(iter.next(), None);
87    assert_eq!(iter.next(), None);
88    assert_eq!(iter.next_back(), Some("paths"));
89    assert_eq!(iter.next_back(), Some("some"));
90    assert_eq!(iter.next_back(), Some("var"));
91    assert_eq!(iter.next_back(), None);
92    assert_eq!(iter.next_back(), None);
93
94    println!("{iter:?}");
95
96    // assert_eq!(iter.next(), Some("var"));
97}