mod html; mod rss; mod static_files; mod txt; use crate::post::Post; use crate::template::Context; use std::io::Result; use std::path::Path; type Generator = fn(&Path, &Path, &Path, &Context) -> Result<()>; pub fn generate( static_directory: &Path, template_directory: &Path, output_directory: &Path, posts: &[Post], ) -> Result<()> { let generators = available_generators(); let context = Post::to_template_context(posts); for generator in generators { generator( static_directory, template_directory, output_directory, &context, )?; } Ok(()) } fn available_generators() -> Vec { vec![ static_files::generate, // These three are actually the same. Can generalize, don't know how in rust yet. html::generate, rss::generate, txt::generate, ] } #[cfg(test)] mod tests { use std::fs::create_dir_all; use super::*; use crate::metadata::Metadata; use crate::post::Post; use test_utilities::*; #[test] fn test_generates() { let test_dir = setup_test_dir(); let static_dir = test_dir.join("static"); let template_dir = test_dir.join("templates"); let output_dir = test_dir.join("output"); create_dir_all(&static_dir).expect("Could not create static directory"); create_dir_all(&template_dir).expect("Could not create template directory"); create_dir_all(&output_dir).expect("Could not create output directory"); create_test_file(&static_dir.join("file.txt"), "wow"); create_test_file( &template_dir.join("index.html"), "\ {{~ posts:post }} {{= post.html }} {{~}} ", ); create_test_file( &template_dir.join("feed.xml"), "\ {{~ posts:post }} {{= post.id }} {{~}} ", ); create_test_file( &template_dir.join("index.txt"), "\ {{~ posts:post }} {{= post.raw }} {{~}} ", ); let posts = vec![ Post { metadata: Metadata { id: "1736035200000".to_string(), created_on: 1_736_035_200_000, }, index: 9, html: "

Generatorial

".to_string(), raw: "electricity generator".to_string(), }, Post { metadata: Metadata { id: "1736045200000".to_string(), created_on: 1_736_045_200_000, }, index: 10, html: "

Generation

".to_string(), raw: "kero kero".to_string(), }, ]; generate(&static_dir, &template_dir, &output_dir, &posts).expect("Generate failed"); assert_file_contents(&output_dir.join("file.txt"), "wow"); assert_file_contents( &output_dir.join("index.html"), "\

Generatorial

Generation

", ); assert_file_contents( &output_dir.join("feed.xml"), "\ 1736035200000 1736045200000 ", ); cleanup_test_dir(&test_dir); } #[test] fn test_fails_if_directories_do_not_exist() { let test_dir = setup_test_dir(); let static_dir = test_dir.join("static"); let template_dir = test_dir.join("templates"); let output_dir = test_dir.join("output"); let posts = vec![]; let result = generate(&static_dir, &template_dir, &output_dir, &posts); assert!(result.is_err()); cleanup_test_dir(&test_dir); } #[test] fn test_fails_if_a_generator_fails() { let test_dir = setup_test_dir(); let static_dir = test_dir.join("static"); let template_dir = test_dir.join("templates"); let output_dir = test_dir.join("output"); create_dir_all(&static_dir).expect("Could not create static directory"); create_dir_all(&template_dir).expect("Could not create template directory"); create_dir_all(&output_dir).expect("Could not create output directory"); create_test_file(&static_dir.join("file.txt"), "wow"); create_test_file( &template_dir.join("index.html"), "\ {{~ posts:post }} {{ post.html }} {{~}} ", ); let posts = vec![ Post { metadata: Metadata { id: "1736035200000".to_string(), created_on: 1_736_035_200_000, }, index: 9, html: "

Generatorial

".to_string(), raw: "electricity generator".to_string(), }, Post { metadata: Metadata { id: "1736045200000".to_string(), created_on: 1_736_045_200_000, }, index: 10, html: "

Generation

".to_string(), raw: "kero kero".to_string(), }, ]; let result = generate(&static_dir, &template_dir, &output_dir, &posts); assert!(result.is_err()); cleanup_test_dir(&test_dir); } }