mod image_export; mod litematica; mod mcfunction; use lib::{BlockPalette, StructureExporter}; pub use image_export::PngExporter; pub use litematica::LitematicaExporter; pub use mcfunction::McFunctionExporter; type ExporterFactory = fn(&BlockPalette) -> Box; const REGISTRY: &[(&str, ExporterFactory)] = &[ ("mcfunction", |p| Box::new(McFunctionExporter::new(p))), ("litematica", |p| Box::new(LitematicaExporter::new(p))), // cell_size=16 default; CLI uses build_png() to honour --cell-size ("png", |p| Box::new(PngExporter::new(p, 16))), ]; pub fn available_names() -> Vec<&'static str> { REGISTRY.iter().map(|(name, _)| *name).collect() } pub fn build_png(palette: &BlockPalette, cell_size: u32) -> Box { Box::new(PngExporter::new(palette, cell_size)) } pub fn build(name: &str, palette: &BlockPalette) -> Option> { REGISTRY.iter() .find(|(n, _)| *n == name) .map(|(_, factory)| factory(palette)) } #[cfg(test)] mod tests { use super::*; fn dummy_palette() -> BlockPalette { serde_json::from_str(r#"{ "name": "test", "blocks": { "body": "minecraft:stone", "outline": "minecraft:cobblestone", "shadow": "minecraft:gravel" } }"#).unwrap() } #[test] fn build_mcfunction_returns_some() { let p = dummy_palette(); assert!(build("mcfunction", &p).is_some()); } #[test] fn build_litematica_returns_some() { let p = dummy_palette(); assert!(build("litematica", &p).is_some()); } #[test] fn build_unknown_returns_none() { let p = dummy_palette(); assert!(build("foo", &p).is_none()); } #[test] fn available_names_contains_both() { let names = available_names(); assert!(names.contains(&"mcfunction")); assert!(names.contains(&"litematica")); } }