Skip to content
Snippets Groups Projects
cli_args.rs 3.89 KiB
Newer Older
Louis's avatar
Louis committed
use clap::Parser;
use image::ImageFormat;
Louis's avatar
Louis committed
use serde::{Deserialize, Serialize};

Louis's avatar
Louis committed
use crate::commands::{
	Atlas, Extract, Extrude, Flip, Info, Palette, Pipeline, Reduce, Remap, Rotate, Scale, Split,
Louis's avatar
Louis committed
};
Louis's avatar
Louis committed

use crate::load_image;
Louis's avatar
Louis committed

/// 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)]
Louis's avatar
Louis committed
#[clap(name = "crunch")]
Louis's avatar
Louis committed
#[clap(author = "Louis Capitanchik <louis@microhacks.co.uk>")]
Louis's avatar
Louis committed
#[clap(version = "0.7.0")]
Louis's avatar
Louis committed
#[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),
Louis's avatar
Louis committed
	#[clap(name = "pipeline")]
	#[serde(alias = "pipeline")]
	Pipeline(Pipeline),
Louis's avatar
Louis committed
	#[clap(name = "reduce")]
	#[serde(alias = "reduce")]
	Reduce(Reduce),
	#[clap(name = "split")]
	#[serde(alias = "split")]
	Split(Split),
Louis's avatar
Louis committed
	#[clap(name = "atlas")]
	#[serde(alias = "atlas")]
	Atlas(Atlas),
	#[clap(name = "extract")]
	#[serde(alias = "extract")]
	Extract(Extract),
	#[clap(name = "info")]
	#[serde(alias = "info")]
	Info(Info),
Louis's avatar
Louis committed
}

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)
Louis's avatar
Louis committed
			}
			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)
Louis's avatar
Louis committed
			}
			Args::Palette(palette) => {
				let image = load_image(&palette.input, None)?;
				palette.run(&image)
Louis's avatar
Louis committed
			}
			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)
Louis's avatar
Louis committed
			}
			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)
Louis's avatar
Louis committed
			}
Louis's avatar
Louis committed
			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)
			}
Louis's avatar
Louis committed
			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(),
Louis's avatar
Louis committed
			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)?;

				if let Some(out_path) = &info.output {
					let file = std::fs::File::create(out_path)?;
					serde_json::to_writer_pretty(file, &output)?;
				} else {
					let stdout = std::io::stdout();
					let stdout_handle = stdout.lock();
					serde_json::to_writer_pretty(stdout_handle, &output)?;