luaur_cli_lib/functions/
normalize_path.rs1use crate::functions::is_absolute_path::is_absolute_path;
2use crate::functions::split_path::split_path;
3
4pub fn normalize_path(path: &str) -> alloc::string::String {
5 let components: alloc::vec::Vec<&str> = split_path(path);
6 let mut normalized_components: alloc::vec::Vec<&str> = alloc::vec::Vec::new();
7
8 let is_absolute = is_absolute_path(path);
9
10 let start_index = if is_absolute { 1 } else { 0 };
12 for i in start_index..components.len() {
13 let component = components[i];
14 if component == ".." {
15 if normalized_components.is_empty() {
16 if !is_absolute {
17 normalized_components.push("..");
18 }
19 } else if *normalized_components.last().unwrap() == ".." {
20 normalized_components.push("..");
21 } else {
22 normalized_components.pop();
23 }
24 } else if !component.is_empty() && component != "." {
25 normalized_components.push(component);
26 }
27 }
28
29 let mut normalized_path = alloc::string::String::new();
30
31 if is_absolute {
33 normalized_path.push_str(components[0]);
35 normalized_path.push('/');
36 } else if normalized_components.is_empty() || normalized_components[0] != ".." {
37 normalized_path.push_str("./");
38 }
39
40 for (idx, component) in normalized_components.iter().enumerate() {
42 if idx != 0 {
43 normalized_path.push('/');
44 }
45 normalized_path.push_str(component);
46 }
47
48 let bytes = normalized_path.as_bytes();
49 if bytes.len() >= 2 && bytes[bytes.len() - 1] == b'.' && bytes[bytes.len() - 2] == b'.' {
50 normalized_path.push('/');
51 }
52
53 normalized_path
54}