exocore_core/utils/
path.rs1use std::path::{Component, Path, PathBuf};
2
3pub fn child_to_abs_path<P: AsRef<Path>, C: AsRef<Path>>(parent: P, child: C) -> PathBuf {
4 let parent_path = parent.as_ref();
5 let child_path = child.as_ref();
6
7 if child_path.is_absolute() {
8 return child_path.to_path_buf();
9 }
10
11 let parent_path_buf = PathBuf::from(parent_path);
12 clean_path(parent_path_buf.join(child_path))
13}
14
15pub fn child_to_relative_path<P: AsRef<Path>, C: AsRef<Path>>(parent: P, child: C) -> PathBuf {
16 child
17 .as_ref()
18 .strip_prefix(parent.as_ref())
19 .unwrap_or_else(|_| child.as_ref())
20 .to_owned()
21}
22
23pub fn clean_path<P: AsRef<Path>>(path: P) -> PathBuf {
24 let path = path.as_ref();
25 let mut out = PathBuf::new();
26
27 for (i, component) in path.components().enumerate() {
28 match component {
29 Component::CurDir if i > 0 => {}
30 other => out.push(other),
31 }
32 }
33
34 out
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40
41 #[test]
42 fn test_clean_path() {
43 assert_eq!(clean_path("./test/./test"), PathBuf::from("./test/test"));
44 assert_eq!(clean_path("./test/././test"), PathBuf::from("./test/test"));
45 assert_eq!(clean_path("/test/test"), PathBuf::from("/test/test"));
46 }
47
48 #[test]
49 fn to_absolute_path() {
50 assert_eq!(
51 child_to_abs_path("/parent", "child"),
52 PathBuf::from("/parent/child")
53 );
54 assert_eq!(
55 child_to_abs_path("/parent", "./child"),
56 PathBuf::from("/parent/child")
57 );
58 assert_eq!(
59 child_to_abs_path("/parent", "././child"),
60 PathBuf::from("/parent/child")
61 );
62 assert_eq!(child_to_abs_path("/", "././child"), PathBuf::from("/child"));
63 }
64
65 #[test]
66 fn to_relative_path() {
67 assert_eq!(
68 child_to_relative_path("/parent", "/parent/child"),
69 PathBuf::from("child")
70 );
71 assert_eq!(
72 child_to_relative_path("/bleh", "/parent/child"),
73 PathBuf::from("/parent/child")
74 );
75 }
76}