use clap::Parser; use image::ImageFormat; use serde::{Deserialize, Serialize}; use crate::commands::{ Atlas, Extract, Extrude, Flip, Info, Palette, Pipeline, Reduce, Remap, Rotate, Scale, Split, }; use crate::load_image; /// Crunch is a set of utilities for quickly and easily processing a batch of files, either directly /// or by defining pipelines #[derive(Parser, Debug, Clone, Serialize, Deserialize)] #[clap(name = "crunch")] #[clap(author = "Louis Capitanchik <louis@microhacks.co.uk>")] #[clap(version = "0.5.1")] #[clap(about, long_about = None)] #[serde(tag = "command", content = "params")] pub enum Args { #[clap(name = "rotate")] #[serde(alias = "rotate")] Rotate(Rotate), #[clap(name = "extrude")] #[serde(alias = "extrude")] Extrude(Extrude), #[clap(name = "palette")] #[serde(alias = "palette")] Palette(Palette), #[clap(name = "scale")] #[serde(alias = "scale")] Scale(Scale), #[clap(name = "flip")] #[serde(alias = "flip")] Flip(Flip), #[clap(name = "remap")] #[serde(alias = "remap")] Remap(Remap), #[clap(name = "pipeline")] #[serde(alias = "pipeline")] Pipeline(Pipeline), #[clap(name = "reduce")] #[serde(alias = "reduce")] Reduce(Reduce), #[clap(name = "split")] #[serde(alias = "split")] Split(Split), #[clap(name = "atlas")] #[serde(alias = "atlas")] Atlas(Atlas), #[clap(name = "extract")] #[serde(alias = "extract")] Extract(Extract), #[clap(name = "info")] #[serde(alias = "info")] Info(Info), } impl Args { pub fn run(&self) -> anyhow::Result<()> { match &self { Args::Rotate(rotate) => { let image = load_image(&rotate.input, None)?; let output = rotate.run(&image)?; output .save_with_format(&rotate.output, ImageFormat::Png) .map_err(anyhow::Error::from) } Args::Extrude(extrude) => { let image = load_image(&extrude.input, None)?; let output = extrude.run(&image)?; output .save_with_format(&extrude.output, ImageFormat::Png) .map_err(anyhow::Error::from) } Args::Palette(palette) => { let image = load_image(&palette.input, None)?; palette.run(&image) } Args::Scale(scale) => { let image = load_image(&scale.input, None)?; let output = scale.run(&image)?; output .save_with_format(&scale.output, ImageFormat::Png) .map_err(anyhow::Error::from) } Args::Flip(flip) => { let image = load_image(&flip.input, None)?; let output = flip.run(&image)?; output .save_with_format(&flip.output, ImageFormat::Png) .map_err(anyhow::Error::from) } Args::Remap(remap) => { let image_data = load_image(&remap.input, None)?; let palette_data = load_image(&remap.palette, None)?; let image_palette = Palette::extract_from(&image_data)?; let target_palette = Palette::extract_from(&palette_data)?; let mappings = Palette::calculate_mapping(&image_palette, &target_palette); let output = Remap::remap_image(image_data, mappings)?; output .save_with_format(&remap.output, ImageFormat::Png) .map_err(anyhow::Error::from) } Args::Reduce(reduce) => { if let Some(amount) = reduce.colours { log::info!("Num cols {}", amount); } else { log::info!("No Limit"); } Ok(()) } Args::Split(split) => { let image = load_image(&split.input, None)?; split.run(&image) } Args::Pipeline(pipeline) => pipeline.execute(), Args::Atlas(atlas) => atlas.run(), Args::Extract(extract) => { let image_data = load_image(&extract.input, None)?; extract.run(&image_data) } Args::Info(info) => { let image_data = load_image(&info.input, None)?; let output = info.run(&image_data)?; { let file = std::fs::File::create(&info.output)?; serde_json::to_writer_pretty(file, &output)?; } Ok(()) } } } }