1use crate::inner::PathInner;
2
3#[derive(Debug)]
4pub struct Segments<'a> {
5 path: &'a PathInner,
6 pos: Option<usize>,
7 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 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 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 }