1const SEP: char = '.';
2
3#[derive(Clone, Copy, Debug)]
6pub enum Path<'a> {
7 End,
8 Pair(&'a str, &'a Path<'a>),
9}
10
11impl<'a> Path<'a> {
12 pub fn new(s: &str) -> Path {
13 Path::Pair(s, &Path::End)
14 }
15
16 pub fn parts(&self) -> Parts {
17 Parts { path: *self }
18 }
19
20 pub fn prepend(&'a self, first: &'a str) -> Path<'a> {
21 Path::Pair(first, self)
22 }
23
24 pub fn deconstruct(&self) -> Option<(&'a str, Path<'a>)> {
25 let mut node = self;
26
27 while let &Path::Pair(first, rest) = node {
28 let mut chars = first.chars();
29 let mut substr = first;
30
31 while let Some(c) = chars.next() {
32 if c == SEP {
33 substr = chars.as_str();
34 continue;
35 }
36
37 return Some(
38 if let Some(end) = substr.find(SEP) {
39 let first = &substr[..end];
40 let second = &substr[end + SEP.len_utf8()..];
41 (first, Path::Pair(second, rest))
42 } else {
43 (substr, *rest)
44 }
45 );
46 }
47
48 node = rest;
49 }
50
51 None
52 }
53
54 pub fn to_owned(&self) -> PathBuf {
55 let mut buf = PathBuf::new();
56 let mut cur = self;
57
58 if let &Path::Pair(first, next) = cur {
59 buf.push_str(first);
60 cur = next;
61 } else {
62 return buf;
63 }
64
65 while let &Path::Pair(first, next) = cur {
66 buf.push(SEP);
67 buf.push_str(first);
68 cur = next;
69 }
70
71 buf
72 }
73}
74
75#[derive(Debug)]
78pub struct Parts<'a> {
79 path: Path<'a>,
80}
81
82impl<'a> Iterator for Parts<'a> {
83 type Item = &'a str;
84
85 fn next(&mut self) -> Option<Self::Item> {
86 let (res, path) = match self.path.deconstruct() {
87 Some((res, path)) => (Some(res), path),
88 None => (None, Path::End),
89 };
90
91 self.path = path;
92 res
93 }
94}
95
96impl<'a> Parts<'a> {
97 pub fn as_path(&self) -> Path {
98 self.path
99 }
100}
101
102pub type PathBuf = String;