aboutsummaryrefslogtreecommitdiff
path: root/crates/paths
diff options
context:
space:
mode:
Diffstat (limited to 'crates/paths')
-rw-r--r--crates/paths/src/lib.rs100
1 files changed, 97 insertions, 3 deletions
diff --git a/crates/paths/src/lib.rs b/crates/paths/src/lib.rs
index c7ce0c42f..1b259682d 100644
--- a/crates/paths/src/lib.rs
+++ b/crates/paths/src/lib.rs
@@ -28,6 +28,12 @@ impl AsRef<Path> for AbsPathBuf {
28 } 28 }
29} 29}
30 30
31impl AsRef<AbsPath> for AbsPathBuf {
32 fn as_ref(&self) -> &AbsPath {
33 self.as_path()
34 }
35}
36
31impl TryFrom<PathBuf> for AbsPathBuf { 37impl TryFrom<PathBuf> for AbsPathBuf {
32 type Error = PathBuf; 38 type Error = PathBuf;
33 fn try_from(path_buf: PathBuf) -> Result<AbsPathBuf, PathBuf> { 39 fn try_from(path_buf: PathBuf) -> Result<AbsPathBuf, PathBuf> {
@@ -45,9 +51,19 @@ impl TryFrom<&str> for AbsPathBuf {
45 } 51 }
46} 52}
47 53
54impl PartialEq<AbsPath> for AbsPathBuf {
55 fn eq(&self, other: &AbsPath) -> bool {
56 self.as_path() == other
57 }
58}
59
48impl AbsPathBuf { 60impl AbsPathBuf {
61 pub fn assert(path: PathBuf) -> AbsPathBuf {
62 AbsPathBuf::try_from(path)
63 .unwrap_or_else(|path| panic!("expected absolute path, got {}", path.display()))
64 }
49 pub fn as_path(&self) -> &AbsPath { 65 pub fn as_path(&self) -> &AbsPath {
50 AbsPath::new_unchecked(self.0.as_path()) 66 AbsPath::assert(self.0.as_path())
51 } 67 }
52 pub fn pop(&mut self) -> bool { 68 pub fn pop(&mut self) -> bool {
53 self.0.pop() 69 self.0.pop()
@@ -77,21 +93,99 @@ impl<'a> TryFrom<&'a Path> for &'a AbsPath {
77 if !path.is_absolute() { 93 if !path.is_absolute() {
78 return Err(path); 94 return Err(path);
79 } 95 }
80 Ok(AbsPath::new_unchecked(path)) 96 Ok(AbsPath::assert(path))
81 } 97 }
82} 98}
83 99
84impl AbsPath { 100impl AbsPath {
85 fn new_unchecked(path: &Path) -> &AbsPath { 101 pub fn assert(path: &Path) -> &AbsPath {
102 assert!(path.is_absolute());
86 unsafe { &*(path as *const Path as *const AbsPath) } 103 unsafe { &*(path as *const Path as *const AbsPath) }
87 } 104 }
88 105
106 pub fn parent(&self) -> Option<&AbsPath> {
107 self.0.parent().map(AbsPath::assert)
108 }
89 pub fn join(&self, path: impl AsRef<Path>) -> AbsPathBuf { 109 pub fn join(&self, path: impl AsRef<Path>) -> AbsPathBuf {
90 self.as_ref().join(path).try_into().unwrap() 110 self.as_ref().join(path).try_into().unwrap()
91 } 111 }
92 pub fn normalize(&self) -> AbsPathBuf { 112 pub fn normalize(&self) -> AbsPathBuf {
93 AbsPathBuf(normalize_path(&self.0)) 113 AbsPathBuf(normalize_path(&self.0))
94 } 114 }
115 pub fn to_path_buf(&self) -> AbsPathBuf {
116 AbsPathBuf::try_from(self.0.to_path_buf()).unwrap()
117 }
118 pub fn strip_prefix(&self, base: &AbsPath) -> Option<&RelPath> {
119 self.0.strip_prefix(base).ok().map(RelPath::new_unchecked)
120 }
121}
122
123#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
124pub struct RelPathBuf(PathBuf);
125
126impl From<RelPathBuf> for PathBuf {
127 fn from(RelPathBuf(path_buf): RelPathBuf) -> PathBuf {
128 path_buf
129 }
130}
131
132impl ops::Deref for RelPathBuf {
133 type Target = RelPath;
134 fn deref(&self) -> &RelPath {
135 self.as_path()
136 }
137}
138
139impl AsRef<Path> for RelPathBuf {
140 fn as_ref(&self) -> &Path {
141 self.0.as_path()
142 }
143}
144
145impl TryFrom<PathBuf> for RelPathBuf {
146 type Error = PathBuf;
147 fn try_from(path_buf: PathBuf) -> Result<RelPathBuf, PathBuf> {
148 if !path_buf.is_relative() {
149 return Err(path_buf);
150 }
151 Ok(RelPathBuf(path_buf))
152 }
153}
154
155impl TryFrom<&str> for RelPathBuf {
156 type Error = PathBuf;
157 fn try_from(path: &str) -> Result<RelPathBuf, PathBuf> {
158 RelPathBuf::try_from(PathBuf::from(path))
159 }
160}
161
162impl RelPathBuf {
163 pub fn as_path(&self) -> &RelPath {
164 RelPath::new_unchecked(self.0.as_path())
165 }
166}
167
168#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
169#[repr(transparent)]
170pub struct RelPath(Path);
171
172impl ops::Deref for RelPath {
173 type Target = Path;
174 fn deref(&self) -> &Path {
175 &self.0
176 }
177}
178
179impl AsRef<Path> for RelPath {
180 fn as_ref(&self) -> &Path {
181 &self.0
182 }
183}
184
185impl RelPath {
186 pub fn new_unchecked(path: &Path) -> &RelPath {
187 unsafe { &*(path as *const Path as *const RelPath) }
188 }
95} 189}
96 190
97// https://github.com/rust-lang/cargo/blob/79c769c3d7b4c2cf6a93781575b7f592ef974255/src/cargo/util/paths.rs#L60-L85 191// https://github.com/rust-lang/cargo/blob/79c769c3d7b4c2cf6a93781575b7f592ef974255/src/cargo/util/paths.rs#L60-L85