diff options
Diffstat (limited to 'crates/vfs/src/vfs_path.rs')
-rw-r--r-- | crates/vfs/src/vfs_path.rs | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/crates/vfs/src/vfs_path.rs b/crates/vfs/src/vfs_path.rs index 944a702df..022a0be1e 100644 --- a/crates/vfs/src/vfs_path.rs +++ b/crates/vfs/src/vfs_path.rs | |||
@@ -48,6 +48,24 @@ impl VfsPath { | |||
48 | (VfsPathRepr::VirtualPath(_), _) => false, | 48 | (VfsPathRepr::VirtualPath(_), _) => false, |
49 | } | 49 | } |
50 | } | 50 | } |
51 | pub fn parent(&self) -> Option<VfsPath> { | ||
52 | let mut parent = self.clone(); | ||
53 | if parent.pop() { | ||
54 | Some(parent) | ||
55 | } else { | ||
56 | None | ||
57 | } | ||
58 | } | ||
59 | |||
60 | pub fn name_and_extension(&self) -> Option<(&str, Option<&str>)> { | ||
61 | match &self.0 { | ||
62 | VfsPathRepr::PathBuf(p) => Some(( | ||
63 | p.file_stem()?.to_str()?, | ||
64 | p.extension().and_then(|extension| extension.to_str()), | ||
65 | )), | ||
66 | VfsPathRepr::VirtualPath(p) => p.name_and_extension(), | ||
67 | } | ||
68 | } | ||
51 | 69 | ||
52 | // Don't make this `pub` | 70 | // Don't make this `pub` |
53 | pub(crate) fn encode(&self, buf: &mut Vec<u8>) { | 71 | pub(crate) fn encode(&self, buf: &mut Vec<u8>) { |
@@ -268,4 +286,60 @@ impl VirtualPath { | |||
268 | res.0 = format!("{}/{}", res.0, path); | 286 | res.0 = format!("{}/{}", res.0, path); |
269 | Some(res) | 287 | Some(res) |
270 | } | 288 | } |
289 | |||
290 | pub fn name_and_extension(&self) -> Option<(&str, Option<&str>)> { | ||
291 | let file_path = if self.0.ends_with('/') { &self.0[..&self.0.len() - 1] } else { &self.0 }; | ||
292 | let file_name = match file_path.rfind('/') { | ||
293 | Some(position) => &file_path[position + 1..], | ||
294 | None => file_path, | ||
295 | }; | ||
296 | |||
297 | if file_name.is_empty() { | ||
298 | None | ||
299 | } else { | ||
300 | let mut file_stem_and_extension = file_name.rsplitn(2, '.'); | ||
301 | let extension = file_stem_and_extension.next(); | ||
302 | let file_stem = file_stem_and_extension.next(); | ||
303 | |||
304 | match (file_stem, extension) { | ||
305 | (None, None) => None, | ||
306 | (None, Some(_)) | (Some(""), Some(_)) => Some((file_name, None)), | ||
307 | (Some(file_stem), extension) => Some((file_stem, extension)), | ||
308 | } | ||
309 | } | ||
310 | } | ||
311 | } | ||
312 | |||
313 | #[cfg(test)] | ||
314 | mod tests { | ||
315 | use super::*; | ||
316 | |||
317 | #[test] | ||
318 | fn virtual_path_extensions() { | ||
319 | assert_eq!(VirtualPath("/".to_string()).name_and_extension(), None); | ||
320 | assert_eq!( | ||
321 | VirtualPath("/directory".to_string()).name_and_extension(), | ||
322 | Some(("directory", None)) | ||
323 | ); | ||
324 | assert_eq!( | ||
325 | VirtualPath("/directory/".to_string()).name_and_extension(), | ||
326 | Some(("directory", None)) | ||
327 | ); | ||
328 | assert_eq!( | ||
329 | VirtualPath("/directory/file".to_string()).name_and_extension(), | ||
330 | Some(("file", None)) | ||
331 | ); | ||
332 | assert_eq!( | ||
333 | VirtualPath("/directory/.file".to_string()).name_and_extension(), | ||
334 | Some((".file", None)) | ||
335 | ); | ||
336 | assert_eq!( | ||
337 | VirtualPath("/directory/.file.rs".to_string()).name_and_extension(), | ||
338 | Some((".file", Some("rs"))) | ||
339 | ); | ||
340 | assert_eq!( | ||
341 | VirtualPath("/directory/file.rs".to_string()).name_and_extension(), | ||
342 | Some(("file", Some("rs"))) | ||
343 | ); | ||
344 | } | ||
271 | } | 345 | } |