From acd456c22a0e710c195a06e3eda486de0bff0c4b Mon Sep 17 00:00:00 2001 From: Matthew Gordon Date: Mon, 10 Nov 2025 20:28:07 -0400 Subject: [PATCH] Move file IO functions in EditorBuffer to io submodule --- core/src/editor_buffer/io.rs | 84 +++++++++++++++++++++++++++++++++++ core/src/editor_buffer/mod.rs | 79 +------------------------------- core/src/lib.rs | 2 +- 3 files changed, 86 insertions(+), 79 deletions(-) create mode 100644 core/src/editor_buffer/io.rs diff --git a/core/src/editor_buffer/io.rs b/core/src/editor_buffer/io.rs new file mode 100644 index 0000000..3e577e2 --- /dev/null +++ b/core/src/editor_buffer/io.rs @@ -0,0 +1,84 @@ +use std::path::PathBuf; + +use super::{CommandResponse, EditorBuffer}; +use crate::{Point, TextBuffer, TextBufferWriter}; + +impl EditorBuffer { + pub fn open_file(&mut self, filepath: PathBuf) -> CommandResponse { + match std::fs::File::open(&filepath) { + Ok(mut file) => { + let mut buffer = TextBuffer::new(); + match std::io::copy(&mut file, &mut TextBufferWriter::new(&mut buffer)) { + Ok(bytes_read) => { + let msg = format!( + "Read {bytes_read} bytes from \"{}\"", + filepath.to_string_lossy() + ); + self.filepath = Some(filepath); + self.cursor = Point::default(); + self.buffer = buffer; + CommandResponse::Success(msg) + } + Err(err) => CommandResponse::Failure(format!("{}", err)), + } + } + Err(err) => { + if err.kind() == std::io::ErrorKind::NotFound { + CommandResponse::Failure(format!( + "File not found: \"{}\"", + filepath.to_string_lossy() + )) + } else { + CommandResponse::Failure(format!("{}", err)) + } + } + } + } + + pub fn save_file(&mut self, _filepath: Option) -> CommandResponse { + todo!() + } +} + +#[cfg(test)] +mod tests { + use crate::{Command, CommandResponse, TextBufferReader, EditorBuffer}; + use std::io::Read; + use std::path::PathBuf; + + #[test] + fn load_file_loads_expected_contents() { + let test_file_path: PathBuf = [ + env!("CARGO_MANIFEST_DIR"), + r"test_data/Les_Trois_Mousquetaires.txt", + ] + .iter() + .collect(); + let expected_text = std::fs::read_to_string(&test_file_path).unwrap(); + let mut target = EditorBuffer::new(); + assert!(matches!( + target.execute(Command::OpenFile(test_file_path)), + CommandResponse::Success(_) + )); + + let mut buffer_bytes = Vec::new(); + TextBufferReader::new(&target.buffer) + .read_to_end(&mut buffer_bytes) + .unwrap(); + let buffer_text = String::from_utf8(buffer_bytes).unwrap(); + assert_eq!(&expected_text, &buffer_text); + } + + #[test] + fn load_file_reports_error_with_missing_file() { + let test_file_path: PathBuf = [env!("CARGO_MANIFEST_DIR"), r"test_data/Not_a_File.txt"] + .iter() + .collect(); + let expected_message = format!("File not found: \"{}\"", test_file_path.to_string_lossy()); + let mut target = EditorBuffer::new(); + match target.execute(Command::OpenFile(test_file_path)) { + CommandResponse::Failure(s) => assert_eq!(expected_message, s), + _ => panic!(), + } + } +} diff --git a/core/src/editor_buffer/mod.rs b/core/src/editor_buffer/mod.rs index 957f0d9..5f32d7b 100644 --- a/core/src/editor_buffer/mod.rs +++ b/core/src/editor_buffer/mod.rs @@ -2,6 +2,7 @@ use std::path::PathBuf; use crate::{Point, TextBuffer, TextBufferWriter}; +mod io; mod command; pub use command::{Command, Movement, Unit}; @@ -39,41 +40,6 @@ impl EditorBuffer { } } - fn open_file(&mut self, filepath: PathBuf) -> CommandResponse { - match std::fs::File::open(&filepath) { - Ok(mut file) => { - let mut buffer = TextBuffer::new(); - match std::io::copy(&mut file, &mut TextBufferWriter::new(&mut buffer)) { - Ok(bytes_read) => { - let msg = format!( - "Read {bytes_read} bytes from \"{}\"", - filepath.to_string_lossy() - ); - self.filepath = Some(filepath); - self.cursor = Point::default(); - self.buffer = buffer; - CommandResponse::Success(msg) - } - Err(err) => CommandResponse::Failure(format!("{}", err)), - } - } - Err(err) => { - if err.kind() == std::io::ErrorKind::NotFound { - CommandResponse::Failure(format!( - "File not found: \"{}\"", - filepath.to_string_lossy() - )) - } else { - CommandResponse::Failure(format!("{}", err)) - } - } - } - } - - fn save_file(&mut self, _filepath: Option) -> CommandResponse { - todo!() - } - fn move_cursor_to_point(&mut self, _point: Point) -> CommandResponse { todo!() } @@ -98,46 +64,3 @@ impl EditorBuffer { todo!() } } - -#[cfg(test)] -mod tests { - use super::*; - use crate::TextBufferReader; - use std::io::Read; - - #[test] - fn load_file_loads_expected_contents() { - let test_file_path: PathBuf = [ - env!("CARGO_MANIFEST_DIR"), - r"test_data/Les_Trois_Mousquetaires.txt", - ] - .iter() - .collect(); - let expected_text = std::fs::read_to_string(&test_file_path).unwrap(); - let mut target = EditorBuffer::new(); - assert!(matches!( - target.execute(Command::OpenFile(test_file_path)), - CommandResponse::Success(_) - )); - - let mut buffer_bytes = Vec::new(); - TextBufferReader::new(&target.buffer) - .read_to_end(&mut buffer_bytes) - .unwrap(); - let buffer_text = String::from_utf8(buffer_bytes).unwrap(); - assert_eq!(&expected_text, &buffer_text); - } - - #[test] - fn load_file_reports_error_with_missing_file() { - let test_file_path: PathBuf = [env!("CARGO_MANIFEST_DIR"), r"test_data/Not_a_File.txt"] - .iter() - .collect(); - let expected_message = format!("File not found: \"{}\"", test_file_path.to_string_lossy()); - let mut target = EditorBuffer::new(); - match target.execute(Command::OpenFile(test_file_path)) { - CommandResponse::Failure(s) => assert_eq!(expected_message, s), - _ => panic!(), - } - } -} diff --git a/core/src/lib.rs b/core/src/lib.rs index 54a4f9e..d7abe8d 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -1,4 +1,4 @@ mod text_buffer; pub use text_buffer::{Point, TextBuffer, TextBufferReader, TextBufferWriter}; mod editor_buffer; -pub use editor_buffer::{Command,EditorBuffer}; +pub use editor_buffer::{Command, CommandResponse, EditorBuffer};