diff --git a/core/Cargo.toml b/core/Cargo.toml index 987683a..ce9a89a 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -6,3 +6,4 @@ edition = "2024" [dev-dependencies] ntest = "0.9.3" rand = {version="0.9.2", features=["small_rng", "alloc"]} +tempfile = "3.23.0" diff --git a/core/src/editor_buffer/io.rs b/core/src/editor_buffer/io.rs index 3e577e2..669cac2 100644 --- a/core/src/editor_buffer/io.rs +++ b/core/src/editor_buffer/io.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; use super::{CommandResponse, EditorBuffer}; -use crate::{Point, TextBuffer, TextBufferWriter}; +use crate::{Point, TextBuffer, TextBufferReader, TextBufferWriter}; impl EditorBuffer { pub fn open_file(&mut self, filepath: PathBuf) -> CommandResponse { @@ -35,16 +35,31 @@ impl EditorBuffer { } } - pub fn save_file(&mut self, _filepath: Option) -> CommandResponse { - todo!() + pub fn save_file(&mut self, filepath: Option) -> CommandResponse { + if let Some(filepath) = filepath.as_ref().or(self.filepath.as_ref()) { + match std::fs::File::create(filepath) { + Ok(mut file) => { + match std::io::copy(&mut TextBufferReader::new(&self.buffer), &mut file) { + Ok(bytes_read) => CommandResponse::Success(format!( + "Read {bytes_read} bytes to \"{}\"", + filepath.to_string_lossy() + )), + Err(err) => CommandResponse::Failure(format!("{}", err)), + } + } + Err(err) => CommandResponse::Failure(format!("{}", err)), + } + } else { + CommandResponse::Failure("Attempting to same file with no name.".into()) + } } } #[cfg(test)] mod tests { - use crate::{Command, CommandResponse, TextBufferReader, EditorBuffer}; - use std::io::Read; - use std::path::PathBuf; + use crate::{Command, CommandResponse, EditorBuffer, TextBufferReader}; + use std::{io::Read, path::PathBuf}; + use tempfile::tempdir; #[test] fn load_file_loads_expected_contents() { @@ -81,4 +96,26 @@ mod tests { _ => panic!(), } } + + #[test] + fn save_file_saves_file_with_expected_contents() { + let test_file_path: PathBuf = [ + env!("CARGO_MANIFEST_DIR"), + r"test_data/Les_Trois_Mousquetaires.txt", + ] + .iter() + .collect(); + let mut target = EditorBuffer::new(); + target.execute(Command::OpenFile(test_file_path.clone())); + let temp_dir = tempdir().unwrap(); + let tmp_file_path = temp_dir.path().join(r"Les_Trois_Mousquetaires.txt"); + assert!(matches!( + dbg!(target.execute(Command::SaveAs(tmp_file_path.clone()))), + CommandResponse::Success(_) + )); + + let read_text = std::fs::read_to_string(&tmp_file_path).unwrap(); + let expected_text = std::fs::read_to_string(&test_file_path).unwrap(); + assert_eq!(&expected_text, &read_text); + } }