From 3d799fe8e70450c26bd2295e96c118ec4c0207bc Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 9 Jul 2021 17:02:42 +0200 Subject: [PATCH] Implement `InMemoryFs::rename` --- zed/src/worktree.rs | 53 +++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/zed/src/worktree.rs b/zed/src/worktree.rs index cf5a5e546d..b65275ba1e 100644 --- a/zed/src/worktree.rs +++ b/zed/src/worktree.rs @@ -204,14 +204,15 @@ struct InMemoryFsState { impl InMemoryFsState { fn validate_path(&self, path: &Path) -> Result<()> { - if path - .parent() - .and_then(|path| self.entries.get(path)) - .map_or(false, |e| e.is_dir) + if path.is_absolute() + && path + .parent() + .and_then(|path| self.entries.get(path)) + .map_or(false, |e| e.is_dir) { Ok(()) } else { - Err(anyhow!("invalid ")) + Err(anyhow!("invalid path {:?}", path)) } } @@ -277,23 +278,37 @@ impl InMemoryFs { pub async fn remove(&self, path: &Path) -> Result<()> { let mut state = self.state.write().await; state.validate_path(path)?; - - let mut paths = Vec::new(); - state.entries.retain(|path, _| { - if path.starts_with(path) { - paths.push(path.to_path_buf()); - false - } else { - true - } - }); - for path in paths { - state.emit_event(&path).await; - } - + state.entries.retain(|path, _| !path.starts_with(path)); + state.emit_event(&path).await; Ok(()) } + pub async fn rename(&self, source: &Path, target: &Path) -> Result<()> { + let mut state = self.state.write().await; + state.validate_path(source)?; + state.validate_path(target)?; + if state.entries.contains_key(target) { + Err(anyhow!("target path already exists")) + } else { + let mut removed = Vec::new(); + state.entries.retain(|path, entry| { + if let Ok(relative_path) = path.strip_prefix(source) { + removed.push((relative_path.to_path_buf(), entry.clone())); + false + } else { + true + } + }); + + for (relative_path, entry) in removed { + let new_path = target.join(relative_path); + state.entries.insert(new_path, entry); + } + + Ok(()) + } + } + pub async fn events(&self) -> broadcast::Receiver { self.state.read().await.events_tx.subscribe() }