file_system/fundamentals/path/
components.rs1use core::str::Split;
2
3use super::{Path, SEPARATOR};
4
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub enum Component<'a> {
7 Root,
8 Current,
9 Parent,
10 Normal(&'a str),
11}
12
13impl<'a> From<&'a str> for Component<'a> {
14 fn from(item: &'a str) -> Self {
15 match item {
16 "" => Component::Root,
17 "/" => Component::Root,
18 "." => Component::Current,
19 ".." => Component::Parent,
20 _ => Component::Normal(item),
21 }
22 }
23}
24
25#[derive(Debug, Clone)]
26pub struct Components<'a>(Split<'a, char>);
27
28impl<'a> Components<'a> {
29 pub fn new(path: &'_ Path) -> Components<'_> {
30 Components(path.as_str().split(SEPARATOR))
31 }
32
33 pub fn get_common_components(self, other: Components<'a>) -> usize {
34 self.zip(other).take_while(|(a, b)| a == b).count()
35 }
36}
37
38impl<'a> Iterator for Components<'a> {
39 type Item = Component<'a>;
40
41 fn next(&mut self) -> Option<Self::Item> {
42 self.0.next().map(Component::from)
43 }
44}
45
46impl DoubleEndedIterator for Components<'_> {
47 fn next_back(&mut self) -> Option<Self::Item> {
48 self.0.next_back().map(Component::from)
49 }
50}
51
52#[cfg(test)]
53mod tests {
54
55 use alloc::{vec, vec::Vec};
56
57 use super::*;
58
59 #[test]
60 fn test_components() {
61 assert_eq!(
62 Components::new(Path::from_str("/a/b/c")).collect::<Vec<_>>(),
63 vec![
64 Component::Root,
65 Component::Normal("a"),
66 Component::Normal("b"),
67 Component::Normal("c")
68 ]
69 );
70
71 assert_eq!(
72 Components::new(Path::from_str("/a/./b/c")).collect::<Vec<_>>(),
73 vec![
74 Component::Root,
75 Component::Normal("a"),
76 Component::Current,
77 Component::Normal("b"),
78 Component::Normal("c")
79 ]
80 );
81
82 assert_eq!(
83 Components::new(Path::from_str("a/b/c")).collect::<Vec<_>>(),
84 vec![
85 Component::Normal("a"),
86 Component::Normal("b"),
87 Component::Normal("c")
88 ]
89 );
90
91 assert_eq!(
92 Components::new(Path::from_str("a/./../b/c")).collect::<Vec<_>>(),
93 vec![
94 Component::Normal("a"),
95 Component::Current,
96 Component::Parent,
97 Component::Normal("b"),
98 Component::Normal("c")
99 ]
100 );
101 }
102}