From dad1333b48c38bc7a5628fc0ff5304d003776a85 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 11 Jun 2020 11:04:09 +0200 Subject: New VFS --- crates/vfs/src/vfs_path.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) (limited to 'crates/vfs/src/vfs_path.rs') diff --git a/crates/vfs/src/vfs_path.rs b/crates/vfs/src/vfs_path.rs index de5dc0bf3..0a8a86c62 100644 --- a/crates/vfs/src/vfs_path.rs +++ b/crates/vfs/src/vfs_path.rs @@ -9,9 +9,17 @@ use paths::{AbsPath, AbsPathBuf}; pub struct VfsPath(VfsPathRepr); impl VfsPath { + /// Creates an "in-memory" path from `/`-separates string. + /// This is most useful for testing, to avoid windows/linux differences + pub fn new_virtual_path(path: String) -> VfsPath { + assert!(path.starts_with('/')); + VfsPath(VfsPathRepr::VirtualPath(VirtualPath(path))) + } + pub fn as_path(&self) -> Option<&AbsPath> { match &self.0 { VfsPathRepr::PathBuf(it) => Some(it.as_path()), + VfsPathRepr::VirtualPath(_) => None, } } pub fn join(&self, path: &str) -> VfsPath { @@ -20,11 +28,24 @@ impl VfsPath { let res = it.join(path).normalize(); VfsPath(VfsPathRepr::PathBuf(res)) } + VfsPathRepr::VirtualPath(it) => { + let res = it.join(path); + VfsPath(VfsPathRepr::VirtualPath(res)) + } } } pub fn pop(&mut self) -> bool { match &mut self.0 { VfsPathRepr::PathBuf(it) => it.pop(), + VfsPathRepr::VirtualPath(it) => it.pop(), + } + } + pub fn starts_with(&self, other: &VfsPath) -> bool { + match (&self.0, &other.0) { + (VfsPathRepr::PathBuf(lhs), VfsPathRepr::PathBuf(rhs)) => lhs.starts_with(rhs), + (VfsPathRepr::PathBuf(_), _) => false, + (VfsPathRepr::VirtualPath(lhs), VfsPathRepr::VirtualPath(rhs)) => lhs.starts_with(rhs), + (VfsPathRepr::VirtualPath(_), _) => false, } } } @@ -32,11 +53,12 @@ impl VfsPath { #[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)] enum VfsPathRepr { PathBuf(AbsPathBuf), + VirtualPath(VirtualPath), } impl From for VfsPath { fn from(v: AbsPathBuf) -> Self { - VfsPath(VfsPathRepr::PathBuf(v)) + VfsPath(VfsPathRepr::PathBuf(v.normalize())) } } @@ -44,6 +66,33 @@ impl fmt::Display for VfsPath { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match &self.0 { VfsPathRepr::PathBuf(it) => fmt::Display::fmt(&it.display(), f), + VfsPathRepr::VirtualPath(VirtualPath(it)) => fmt::Display::fmt(it, f), + } + } +} + +#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)] +struct VirtualPath(String); + +impl VirtualPath { + fn starts_with(&self, other: &VirtualPath) -> bool { + self.0.starts_with(&other.0) + } + fn pop(&mut self) -> bool { + let pos = match self.0.rfind('/') { + Some(pos) => pos, + None => return false, + }; + self.0 = self.0[..pos].to_string(); + true + } + fn join(&self, mut path: &str) -> VirtualPath { + let mut res = self.clone(); + while path.starts_with("../") { + assert!(res.pop()); + path = &path["../".len()..] } + res.0 = format!("{}/{}", res.0, path); + res } } -- cgit v1.2.3