diff options
author | Aleksey Kladov <[email protected]> | 2020-06-11 10:04:09 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-06-23 16:51:06 +0100 |
commit | dad1333b48c38bc7a5628fc0ff5304d003776a85 (patch) | |
tree | 29be52a980b4cae72f46a48c48135a15e31641e0 /crates/vfs/src/vfs_path.rs | |
parent | 7aa66371ee3e8b31217513204c8b4f683584419d (diff) |
New VFS
Diffstat (limited to 'crates/vfs/src/vfs_path.rs')
-rw-r--r-- | crates/vfs/src/vfs_path.rs | 51 |
1 files changed, 50 insertions, 1 deletions
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}; | |||
9 | pub struct VfsPath(VfsPathRepr); | 9 | pub struct VfsPath(VfsPathRepr); |
10 | 10 | ||
11 | impl VfsPath { | 11 | impl VfsPath { |
12 | /// Creates an "in-memory" path from `/`-separates string. | ||
13 | /// This is most useful for testing, to avoid windows/linux differences | ||
14 | pub fn new_virtual_path(path: String) -> VfsPath { | ||
15 | assert!(path.starts_with('/')); | ||
16 | VfsPath(VfsPathRepr::VirtualPath(VirtualPath(path))) | ||
17 | } | ||
18 | |||
12 | pub fn as_path(&self) -> Option<&AbsPath> { | 19 | pub fn as_path(&self) -> Option<&AbsPath> { |
13 | match &self.0 { | 20 | match &self.0 { |
14 | VfsPathRepr::PathBuf(it) => Some(it.as_path()), | 21 | VfsPathRepr::PathBuf(it) => Some(it.as_path()), |
22 | VfsPathRepr::VirtualPath(_) => None, | ||
15 | } | 23 | } |
16 | } | 24 | } |
17 | pub fn join(&self, path: &str) -> VfsPath { | 25 | pub fn join(&self, path: &str) -> VfsPath { |
@@ -20,11 +28,24 @@ impl VfsPath { | |||
20 | let res = it.join(path).normalize(); | 28 | let res = it.join(path).normalize(); |
21 | VfsPath(VfsPathRepr::PathBuf(res)) | 29 | VfsPath(VfsPathRepr::PathBuf(res)) |
22 | } | 30 | } |
31 | VfsPathRepr::VirtualPath(it) => { | ||
32 | let res = it.join(path); | ||
33 | VfsPath(VfsPathRepr::VirtualPath(res)) | ||
34 | } | ||
23 | } | 35 | } |
24 | } | 36 | } |
25 | pub fn pop(&mut self) -> bool { | 37 | pub fn pop(&mut self) -> bool { |
26 | match &mut self.0 { | 38 | match &mut self.0 { |
27 | VfsPathRepr::PathBuf(it) => it.pop(), | 39 | VfsPathRepr::PathBuf(it) => it.pop(), |
40 | VfsPathRepr::VirtualPath(it) => it.pop(), | ||
41 | } | ||
42 | } | ||
43 | pub fn starts_with(&self, other: &VfsPath) -> bool { | ||
44 | match (&self.0, &other.0) { | ||
45 | (VfsPathRepr::PathBuf(lhs), VfsPathRepr::PathBuf(rhs)) => lhs.starts_with(rhs), | ||
46 | (VfsPathRepr::PathBuf(_), _) => false, | ||
47 | (VfsPathRepr::VirtualPath(lhs), VfsPathRepr::VirtualPath(rhs)) => lhs.starts_with(rhs), | ||
48 | (VfsPathRepr::VirtualPath(_), _) => false, | ||
28 | } | 49 | } |
29 | } | 50 | } |
30 | } | 51 | } |
@@ -32,11 +53,12 @@ impl VfsPath { | |||
32 | #[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)] | 53 | #[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)] |
33 | enum VfsPathRepr { | 54 | enum VfsPathRepr { |
34 | PathBuf(AbsPathBuf), | 55 | PathBuf(AbsPathBuf), |
56 | VirtualPath(VirtualPath), | ||
35 | } | 57 | } |
36 | 58 | ||
37 | impl From<AbsPathBuf> for VfsPath { | 59 | impl From<AbsPathBuf> for VfsPath { |
38 | fn from(v: AbsPathBuf) -> Self { | 60 | fn from(v: AbsPathBuf) -> Self { |
39 | VfsPath(VfsPathRepr::PathBuf(v)) | 61 | VfsPath(VfsPathRepr::PathBuf(v.normalize())) |
40 | } | 62 | } |
41 | } | 63 | } |
42 | 64 | ||
@@ -44,6 +66,33 @@ impl fmt::Display for VfsPath { | |||
44 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | 66 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
45 | match &self.0 { | 67 | match &self.0 { |
46 | VfsPathRepr::PathBuf(it) => fmt::Display::fmt(&it.display(), f), | 68 | VfsPathRepr::PathBuf(it) => fmt::Display::fmt(&it.display(), f), |
69 | VfsPathRepr::VirtualPath(VirtualPath(it)) => fmt::Display::fmt(it, f), | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | |||
74 | #[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)] | ||
75 | struct VirtualPath(String); | ||
76 | |||
77 | impl VirtualPath { | ||
78 | fn starts_with(&self, other: &VirtualPath) -> bool { | ||
79 | self.0.starts_with(&other.0) | ||
80 | } | ||
81 | fn pop(&mut self) -> bool { | ||
82 | let pos = match self.0.rfind('/') { | ||
83 | Some(pos) => pos, | ||
84 | None => return false, | ||
85 | }; | ||
86 | self.0 = self.0[..pos].to_string(); | ||
87 | true | ||
88 | } | ||
89 | fn join(&self, mut path: &str) -> VirtualPath { | ||
90 | let mut res = self.clone(); | ||
91 | while path.starts_with("../") { | ||
92 | assert!(res.pop()); | ||
93 | path = &path["../".len()..] | ||
47 | } | 94 | } |
95 | res.0 = format!("{}/{}", res.0, path); | ||
96 | res | ||
48 | } | 97 | } |
49 | } | 98 | } |