pub struct Strategy {} use std::path::PathBuf; use std::fs::{copy, create_dir_all}; use crate::file_handler::{File, FileType, FileHandlerStrategy}; impl Strategy { fn handle(&self, source: &PathBuf, destination: &PathBuf, file: &File) { let relative_path = file.path.strip_prefix(&source).unwrap(); let complete_destination = destination.join(relative_path); let destination_parent = complete_destination.parent().unwrap(); create_dir_all(destination_parent).unwrap(); copy(&file.path, &complete_destination).unwrap(); } } impl FileHandlerStrategy for Strategy { fn is(&self, path: &PathBuf) -> bool { !path.is_dir() } fn identify(&self) -> FileType { FileType::File } fn can_handle(&self, file_type: &FileType) -> bool { match file_type { FileType::File => true, _ => false, } } fn handle_html(&self, source: &PathBuf, destination: &PathBuf, file: &File, _l: &str) { return self.handle(source, destination, file); } fn handle_gemini(&self, source: &PathBuf, destination: &PathBuf, file: &File) { return self.handle(source, destination, file); } } #[cfg(test)] mod tests { use super::*; use std::fs; fn setup() -> Strategy { Strategy {} } fn fixtures_dir() -> PathBuf { PathBuf::from("tests/fixtures") } fn fixture_path(filename: &str) -> PathBuf { fixtures_dir().join(filename) } mod file_type_tests { use super::*; #[test] fn identifies_regular_files() { let strategy = setup(); assert!(strategy.is(&fixture_path("image.png"))); assert!(strategy.is(&fixture_path("style.css"))); assert!(!strategy.is(&fixtures_dir())); } #[test] fn identifies_file_type() { let strategy = setup(); assert!(matches!(strategy.identify(), FileType::File)); } #[test] fn handles_correct_file_type() { let strategy = setup(); assert!(strategy.can_handle(&FileType::File)); assert!(!strategy.can_handle(&FileType::Layout)); assert!(!strategy.can_handle(&FileType::Gemini)); assert!(!strategy.can_handle(&FileType::Unknown)); } } mod file_handling_tests { use super::*; #[test] fn copies_single_file() { let strategy = setup(); let source = fixtures_dir(); let output = fixture_path("output"); let file = File { path: fixture_path("image.png"), file_type: FileType::File, }; strategy.handle(&source, &output, &file); let copied_path = output.join("image.png"); assert!(copied_path.exists()); // Verify file contents are identical let original = fs::read(&file.path).unwrap(); let copied = fs::read(&copied_path).unwrap(); assert_eq!(original, copied); // Cleanup let _ = fs::remove_file(copied_path); } #[test] fn copies_nested_file() { let strategy = setup(); let source = fixtures_dir(); let output = fixture_path("output"); let file = File { path: fixture_path("assets/style.css"), file_type: FileType::File, }; strategy.handle(&source, &output, &file); let copied_path = output.join("assets").join("style.css"); assert!(copied_path.exists()); // Verify file contents are identical let original = fs::read(&file.path).unwrap(); let copied = fs::read(&copied_path).unwrap(); assert_eq!(original, copied); // Cleanup let _ = fs::remove_file(copied_path); let _ = fs::remove_dir(output.join("assets")); } #[test] fn handle_html_copies_file() { let strategy = setup(); let source = fixtures_dir(); let output = fixture_path("output_html"); let file = File { path: fixture_path("image.png"), file_type: FileType::File, }; strategy.handle_html(&source, &output, &file, "unused layout"); let copied_path = output.join("image.png"); assert!(copied_path.exists()); // Cleanup let _ = fs::remove_file(copied_path); } #[test] fn handle_gemini_copies_file() { let strategy = setup(); let source = fixtures_dir(); let output = fixture_path("output_gemini"); let file = File { path: fixture_path("image.png"), file_type: FileType::File, }; strategy.handle_gemini(&source, &output, &file); let copied_path = output.join("image.png"); assert!(copied_path.exists()); // Cleanup let _ = fs::remove_file(copied_path); } } }