From c1b886b0ce212038a49ac9d7ba5235d4aeb1d1e6 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 4 Jul 2022 13:00:12 -0700 Subject: [PATCH] Normalize line endings consistently between fake and real FS --- crates/project/src/fs.rs | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/crates/project/src/fs.rs b/crates/project/src/fs.rs index 69b0b7ff3d..17d7264f1d 100644 --- a/crates/project/src/fs.rs +++ b/crates/project/src/fs.rs @@ -174,15 +174,8 @@ impl Fs for RealFs { let buffer_size = text.summary().bytes.min(10 * 1024); let file = smol::fs::File::create(path).await?; let mut writer = smol::io::BufWriter::with_capacity(buffer_size, file); - let mut newline = false; - for chunk in text.chunks() { - for line in chunk.split('\n') { - if newline { - writer.write_all(line_ending.as_str().as_bytes()).await?; - } - writer.write_all(line.as_bytes()).await?; - newline = true; - } + for chunk in chunks(text, line_ending) { + writer.write_all(chunk.as_bytes()).await?; } writer.flush().await?; Ok(()) @@ -659,15 +652,12 @@ impl Fs for FakeFs { let mut state = self.state.lock().await; let path = normalize_path(path); state.validate_path(&path)?; + let content = chunks(text, line_ending).collect(); if let Some(entry) = state.entries.get_mut(&path) { if entry.metadata.is_dir { Err(anyhow!("cannot overwrite a directory with a file")) } else { - entry.content = Some( - text.chunks() - .map(|chunk| chunk.replace('\n', line_ending.as_str())) - .collect(), - ); + entry.content = Some(content); entry.metadata.mtime = SystemTime::now(); state.emit_event(&[path]).await; Ok(()) @@ -682,7 +672,7 @@ impl Fs for FakeFs { is_dir: false, is_symlink: false, }, - content: Some(text.chunks().collect()), + content: Some(content), }; state.entries.insert(path.to_path_buf(), entry); state.emit_event(&[path]).await; @@ -764,6 +754,21 @@ impl Fs for FakeFs { } } +fn chunks(rope: &Rope, line_ending: LineEnding) -> impl Iterator { + rope.chunks().flat_map(move |chunk| { + let mut newline = false; + chunk.split('\n').flat_map(move |line| { + let ending = if newline { + Some(line_ending.as_str()) + } else { + None + }; + newline = true; + ending.into_iter().chain([line]) + }) + }) +} + pub fn normalize_path(path: &Path) -> PathBuf { let mut components = path.components().peekable(); let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() {