1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use std::ffi::OsString;
use std::io;
use std::path::{Path, PathBuf};
use crate::{ParseDot, MAIN_SEPARATOR};
impl ParseDot for Path {
#[allow(clippy::let_unit_value)]
fn parse_dot(&self) -> io::Result<PathBuf> {
let mut size = self.as_os_str().len();
let _cwd = get_cwd_pathbuf!();
let mut tokens = Vec::new();
let mut iter = self.iter();
if let Some(first_token) = iter.next() {
let cwd = get_cwd!(_cwd);
if first_token.eq(".") {
for token in cwd.iter() {
tokens.push(token);
}
size += cwd.as_os_str().len() - 1;
} else if first_token.eq("..") {
let cwd_parent = cwd.parent();
match cwd_parent {
Some(cwd_parent) => {
for token in cwd_parent.iter() {
tokens.push(token);
}
size += cwd_parent.as_os_str().len() - 2;
}
None => {
tokens.push(MAIN_SEPARATOR.as_os_str());
size -= 2;
}
}
} else {
tokens.push(first_token);
}
for token in iter {
if token.eq("..") {
let len = tokens.len();
if len > 0 && (len != 1 || tokens[0].ne(MAIN_SEPARATOR.as_os_str())) {
let removed = tokens.remove(len - 1);
size -= removed.len() + 4;
} else {
size -= 3;
}
} else {
tokens.push(token);
}
}
}
let mut path = OsString::with_capacity(size);
let len = tokens.len();
if len > 0 {
let mut iter = tokens.iter();
if let Some(first_token) = iter.next() {
path.push(first_token);
if len > 1 {
if !first_token.eq(&MAIN_SEPARATOR.as_os_str()) {
path.push(MAIN_SEPARATOR.as_os_str());
}
for &token in iter.take(len - 2) {
path.push(token);
path.push(MAIN_SEPARATOR.as_os_str());
}
path.push(tokens[len - 1]);
}
}
}
let path_buf = PathBuf::from(path);
Ok(path_buf)
}
}