From 9eae97f1d8825c4bfafc89d723f9e9eea2c1b1e2 Mon Sep 17 00:00:00 2001 From: Gato Date: Fri, 19 Jun 2026 14:09:08 +0200 Subject: [PATCH] feat: module application avec render_service et file_service Co-Authored-By: Claude Sonnet 4.6 --- src-tauri/src/application/file_service.rs | 66 +++++++++++++++++++++ src-tauri/src/application/mod.rs | 2 + src-tauri/src/application/render_service.rs | 60 +++++++++++++++++++ src-tauri/src/lib.rs | 1 + 4 files changed, 129 insertions(+) create mode 100644 src-tauri/src/application/file_service.rs create mode 100644 src-tauri/src/application/mod.rs create mode 100644 src-tauri/src/application/render_service.rs diff --git a/src-tauri/src/application/file_service.rs b/src-tauri/src/application/file_service.rs new file mode 100644 index 0000000..e4382d2 --- /dev/null +++ b/src-tauri/src/application/file_service.rs @@ -0,0 +1,66 @@ +use crate::infrastructure::file_repository; +use std::path::Path; + +#[allow(dead_code)] +pub fn list_markdown_files(dir: &str) -> Result, String> { + let path = Path::new(dir); + if !path.is_dir() { + return Err(format!("{dir} n'est pas un dossier")); + } + let mut files = Vec::new(); + file_repository::collect_md_files(path, &mut files).map_err(|e| e.to_string())?; + files.sort(); + Ok(files) +} + +#[cfg(test)] +mod tests { + use super::*; + use std::fs; + + fn tmpdir(name: &str) -> std::path::PathBuf { + std::env::temp_dir().join(name) + } + + #[test] + fn list_markdown_files_sorted() { + let dir = tmpdir("pena_fs_sorted"); + fs::create_dir_all(&dir).unwrap(); + fs::write(dir.join("z.md"), "").unwrap(); + fs::write(dir.join("a.md"), "").unwrap(); + fs::write(dir.join("m.md"), "").unwrap(); + let result = list_markdown_files(dir.to_str().unwrap()).unwrap(); + fs::remove_dir_all(&dir).unwrap(); + assert_eq!(result.len(), 3); + assert!(result[0] < result[1] && result[1] < result[2]); + assert!(result[0].ends_with("a.md")); + assert!(result[2].ends_with("z.md")); + } + + #[test] + fn list_markdown_files_ignores_non_md() { + let dir = tmpdir("pena_fs_non_md"); + fs::create_dir_all(&dir).unwrap(); + fs::write(dir.join("doc.md"), "").unwrap(); + fs::write(dir.join("notes.txt"), "").unwrap(); + let result = list_markdown_files(dir.to_str().unwrap()).unwrap(); + fs::remove_dir_all(&dir).unwrap(); + assert_eq!(result.len(), 1); + assert!(result[0].ends_with("doc.md")); + } + + #[test] + fn list_markdown_files_not_a_dir() { + let result = list_markdown_files("/nonexistent/pena_fs_dir"); + assert!(result.is_err()); + } + + #[test] + fn list_markdown_files_empty_dir() { + let dir = tmpdir("pena_fs_empty"); + fs::create_dir_all(&dir).unwrap(); + let result = list_markdown_files(dir.to_str().unwrap()).unwrap(); + fs::remove_dir_all(&dir).unwrap(); + assert_eq!(result.len(), 0); + } +} diff --git a/src-tauri/src/application/mod.rs b/src-tauri/src/application/mod.rs new file mode 100644 index 0000000..7745604 --- /dev/null +++ b/src-tauri/src/application/mod.rs @@ -0,0 +1,2 @@ +pub mod file_service; +pub mod render_service; diff --git a/src-tauri/src/application/render_service.rs b/src-tauri/src/application/render_service.rs new file mode 100644 index 0000000..820accb --- /dev/null +++ b/src-tauri/src/application/render_service.rs @@ -0,0 +1,60 @@ +use crate::domain::MarkdownRenderer; +use crate::infrastructure::file_repository; + +#[allow(dead_code)] +pub fn render_string(renderer: &dyn MarkdownRenderer, content: &str) -> String { + renderer.render(content) +} + +#[allow(dead_code)] +pub fn render_file(renderer: &dyn MarkdownRenderer, path: &str) -> Result { + let content = file_repository::read_file(path)?; + Ok(renderer.render(&content)) +} + +#[cfg(test)] +mod tests { + use super::*; + use std::fs; + + struct MockRenderer; + + impl MarkdownRenderer for MockRenderer { + fn render(&self, content: &str) -> String { + format!("{content}") + } + } + + #[test] + fn render_string_delegates_to_renderer() { + let renderer = MockRenderer; + let result = render_string(&renderer, "hello"); + assert_eq!(result, "hello"); + } + + #[test] + fn render_string_empty_content() { + let renderer = MockRenderer; + let result = render_string(&renderer, ""); + assert_eq!(result, ""); + } + + #[test] + fn render_file_success() { + let dir = std::env::temp_dir().join("pena_rs_render_file"); + fs::create_dir_all(&dir).unwrap(); + let file = dir.join("test.md"); + fs::write(&file, "world").unwrap(); + let renderer = MockRenderer; + let result = render_file(&renderer, file.to_str().unwrap()); + fs::remove_dir_all(&dir).unwrap(); + assert_eq!(result.unwrap(), "world"); + } + + #[test] + fn render_file_not_found() { + let renderer = MockRenderer; + let result = render_file(&renderer, "/nonexistent/pena_rs_file.md"); + assert!(result.is_err()); + } +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index c5c680a..2970b74 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1,3 +1,4 @@ +mod application; mod core; mod domain; mod infrastructure;