diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000000000000000000000000000000000000..ddac46a818a71283d5b1d79d0d01761aaceb5b84 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,4 @@ +hard_tabs = true +group_imports = "StdExternalCrate" +use_field_init_shorthand = true +use_try_shorthand = true \ No newline at end of file diff --git a/src/cli_args.rs b/src/cli_args.rs index f551cd07a579aeb9424edb32353b99135124f34f..159e911552aa02ceebb1f30ba7131c516863fd6f 100644 --- a/src/cli_args.rs +++ b/src/cli_args.rs @@ -16,10 +16,8 @@ use crate::{load_image, Format}; #[clap(about, long_about = None)] pub struct Args { /// The path to the spritesheet file - // #[clap(short = 'i', long = "in")] in_path: String, /// The path to the output file - // #[clap(short = 'o', long = "out")] out_path: String, /// Force Crunch to read the input file as a specific format diff --git a/src/commands/extrude.rs b/src/commands/extrude.rs index 1229afd2025babadf130045005f1f0c22982555a..168e5057e48d0883a414787ee657576d7f2343de 100644 --- a/src/commands/extrude.rs +++ b/src/commands/extrude.rs @@ -71,8 +71,6 @@ pub fn extrude( pix.0[3].to_u8().unwrap(), ]); - // log::info! - new_image.put_pixel( pad_x + (sprite.tx * space_x) + img_x + x, pad_y + (sprite.ty * space_y) + img_y + y, @@ -82,7 +80,5 @@ pub fn extrude( } } - log::info!("{}", new_image.width() * new_image.height()); - Ok(new_image) } diff --git a/src/commands/flip.rs b/src/commands/flip.rs index ea459d98f0040dbf6a10c3bfeae32e1be2fbec1d..6343cca356401ff2c24d12b28a307078dc196a0d 100644 --- a/src/commands/flip.rs +++ b/src/commands/flip.rs @@ -1,8 +1,9 @@ use clap::ArgEnum; -use image::imageops::FilterType; -use image::{imageops, GenericImage, ImageBuffer, Pixel}; +use image::{imageops, GenericImage, Pixel}; use serde::{Deserialize, Serialize}; +use crate::TypedOutputFormat; + #[derive(Copy, Clone, Serialize, Deserialize, ArgEnum, Debug)] pub enum FlipDirection { #[serde(rename = "vertical")] @@ -13,10 +14,7 @@ pub enum FlipDirection { Both, } -pub fn flip<T: GenericImage>( - image: &T, - dir: FlipDirection, -) -> anyhow::Result<ImageBuffer<T::Pixel, Vec<<T::Pixel as Pixel>::Subpixel>>> +pub fn flip<T: GenericImage>(image: &T, dir: FlipDirection) -> anyhow::Result<TypedOutputFormat<T>> where T::Pixel: 'static, <T::Pixel as Pixel>::Subpixel: 'static, diff --git a/src/commands/palette.rs b/src/commands/palette.rs index 88a23a90f1996522f2c00a339d551a3ad0e7db5e..201f0cf307984a8482e6bb124d2c574b69402104 100644 --- a/src/commands/palette.rs +++ b/src/commands/palette.rs @@ -16,18 +16,17 @@ pub type Palette = Vec<BasicRgba>; pub fn palette(image: &impl GenericImage) -> anyhow::Result<Palette> { let mut colours = HashSet::new(); - for (_, _, pixel) in image.pixels().into_iter() { + for (_, _, pixel) in image.pixels() { let pixel = pixel.to_rgba(); colours.insert(Rgba::from([ pixel.0[0].to_u8().unwrap(), pixel.0[1].to_u8().unwrap(), pixel.0[2].to_u8().unwrap(), pixel.0[3].to_u8().unwrap(), - // &pixel.0.map(|i| i.to_u8().unwrap()) ])); } - Ok(colours.iter().map(|c| BasicRgba::from(c)).collect()) + Ok(colours.iter().map(BasicRgba::from).collect()) } struct HexStringValue(String); @@ -44,7 +43,7 @@ impl HexString for Rgba<u8> { } impl<T: HexString + Clone> HexString for &T { fn as_hex_string(&self) -> HexStringValue { - self.clone().as_hex_string() + (*self).clone().as_hex_string() } } impl UpperHex for HexStringValue { @@ -63,11 +62,9 @@ pub fn write_palette<T: AsRef<Path>>( format: PaletteFormat, outpath: T, ) -> anyhow::Result<()> { + #[allow(clippy::redundant_clone)] let mut sorted = colours.clone(); sorted.sort_by(|pa, pb| { - // format!("{:X}", pa.as_hex_string()) - // .cmp(&format!("{:X}", pb.as_hex_string())) - let hue_a = pa.hue(); let hue_b = pb.hue(); @@ -83,7 +80,7 @@ pub fn write_palette<T: AsRef<Path>>( }); match format { - PaletteFormat::PNG => { + PaletteFormat::Png => { let num_colours = sorted.len(); let image_width = min(16, num_colours); let image_height = if num_colours % 16 > 0 { @@ -103,7 +100,7 @@ pub fn write_palette<T: AsRef<Path>>( out_image.save(outpath)?; } - PaletteFormat::TXT => { + PaletteFormat::Txt => { let mut file = std::fs::File::create(outpath)?; for colour in sorted.iter() { let line = format!("#{:X}\n", colour); @@ -144,13 +141,13 @@ pub fn calculate_mapping(from: &Palette, to: &Palette) -> ColourMapping { match closest { Some(idx) => match to_palette_vectors.get(&idx) { Some(col) => { - out_map.insert(colour.clone(), *col.clone()); + out_map.insert(*colour, **col); } None => { println!("No matching vec for {} with col {:?}", idx, &colour); out_map.insert( - colour.clone(), + *colour, BasicRgba { r: 0, g: 0, @@ -163,7 +160,7 @@ pub fn calculate_mapping(from: &Palette, to: &Palette) -> ColourMapping { None => { println!("No closest for {:?}", &colour); out_map.insert( - colour.clone(), + *colour, BasicRgba { r: 0, g: 0, @@ -175,7 +172,5 @@ pub fn calculate_mapping(from: &Palette, to: &Palette) -> ColourMapping { } } - // println!("{:?}", &out_map); - out_map } diff --git a/src/commands/pipeline.rs b/src/commands/pipeline.rs index 2b3aca2692abf71e936b72fce77bfa9833564f0d..b439d3afe263de5c0f65db791755327f43417090 100644 --- a/src/commands/pipeline.rs +++ b/src/commands/pipeline.rs @@ -1,13 +1,11 @@ use std::collections::HashMap; use std::path::PathBuf; -use std::sync::{Arc, Mutex}; use rayon::prelude::*; use serde::{Deserialize, Serialize}; use thiserror::Error; use crate::cli_args::CrunchCommand; -use crate::utils::Pipeline; use crate::{commands, load_image}; #[derive(Error, Debug)] @@ -22,7 +20,7 @@ pub enum PipelineType { Pipeline { input_path: String, output_path: String, - actions: Vec<crate::cli_args::CrunchCommand>, + actions: Vec<CrunchCommand>, }, Ref { input_path: String, @@ -33,7 +31,7 @@ pub enum PipelineType { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct PipelineRef { - pub actions: Vec<crate::cli_args::CrunchCommand>, + pub actions: Vec<CrunchCommand>, } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -52,7 +50,7 @@ pub fn execute_pipeline<IN: ToString, OUT: ToString>( } let file_contents = std::fs::read(file_path.to_string())?; - let mut pipeline_data: PipelineFile = if path.ends_with(".toml") { + let pipeline_data: PipelineFile = if path.ends_with(".toml") { toml::from_slice(&file_contents)? } else { serde_json::from_slice(&file_contents)? @@ -73,7 +71,7 @@ pub fn execute_pipeline<IN: ToString, OUT: ToString>( reference, } => pipeline_data .refs - .get(reference) + .get(reference.as_str()) .map(|value| (input_path, output_path, value.actions.clone())), }) .for_each(|(input_path, output_path, actions)| { @@ -86,8 +84,6 @@ pub fn execute_pipeline<IN: ToString, OUT: ToString>( }; let mut count = 1; - let total = actions.len(); - for step in actions { match step { CrunchCommand::Extrude { @@ -218,23 +214,21 @@ pub fn execute_pipeline<IN: ToString, OUT: ToString>( let mut outer_target_path = PathBuf::from(output_path); outer_target_path.pop(); - match std::fs::create_dir(&outer_target_path) { - Err(e) => match e.kind() { + if let Err(e) = std::fs::create_dir(&outer_target_path) { + match e.kind() { std::io::ErrorKind::AlreadyExists => { /* This is fine */ } _ => log::error!( "Failed to create containing directory {}; {}", outer_target_path.to_string_lossy(), e ), - }, - _ => {} + } } match file.save(output_path) { Ok(_) => {} Err(e) => { log::error!("Failed to save to {}; {}", output_path, e); - return; } } }); diff --git a/src/commands/remap.rs b/src/commands/remap.rs index d9062fb15989b6c74ff501060ba3688dde3946ae..d1b554541cb73bfd9a7bacd7c6091642d55c9cff 100644 --- a/src/commands/remap.rs +++ b/src/commands/remap.rs @@ -10,7 +10,7 @@ pub fn remap_image( mappings: ColourMapping, ) -> anyhow::Result<OutputFormat> { let mut output = new_image(image.width(), image.height()); - for (x, y, pixel) in image.pixels().into_iter() { + for (x, y, pixel) in image.pixels() { let pixel = pixel.to_rgba(); if pixel.0[3].to_u8().unwrap() == 0 { @@ -32,7 +32,7 @@ pub fn remap_image( y, Rgba::from(BasicRgba { a: basic.a, - ..mapped_data.clone() + ..*mapped_data }), ), None => output.put_pixel(x, y, Rgba::from(BasicRgba::transparent())), diff --git a/src/commands/rotate.rs b/src/commands/rotate.rs index df6858638cf7036b90063336f846e4231817e49e..bcb1c7e1dcd5b7734e84f12604808e8af5cbb43f 100644 --- a/src/commands/rotate.rs +++ b/src/commands/rotate.rs @@ -1,8 +1,9 @@ use clap::ArgEnum; -use image::imageops::FilterType; -use image::{imageops, GenericImage, ImageBuffer, Pixel}; +use image::{imageops, GenericImage, Pixel}; use serde::{Deserialize, Serialize}; +use crate::TypedOutputFormat; + #[derive(Copy, Clone, Serialize, Deserialize, ArgEnum, Debug)] pub enum RotateDegree { #[serde(rename = "90")] @@ -16,7 +17,7 @@ pub enum RotateDegree { pub fn rotate<T: GenericImage>( image: &T, degree: RotateDegree, -) -> anyhow::Result<ImageBuffer<T::Pixel, Vec<<T::Pixel as Pixel>::Subpixel>>> +) -> anyhow::Result<TypedOutputFormat<T>> where T::Pixel: 'static, <T::Pixel as Pixel>::Subpixel: 'static, diff --git a/src/commands/scale.rs b/src/commands/scale.rs index db8a2cb31f751005d158bfed7af05ecb2cb8a1a8..66b3ad69c04dd340fbfcbbfb26722052f5e79633 100644 --- a/src/commands/scale.rs +++ b/src/commands/scale.rs @@ -1,10 +1,9 @@ use image::imageops::FilterType; -use image::{imageops, GenericImage, ImageBuffer, Pixel}; +use image::{imageops, GenericImage, Pixel}; -pub fn rescale<T: GenericImage>( - image: &T, - factor: f32, -) -> anyhow::Result<ImageBuffer<T::Pixel, Vec<<T::Pixel as Pixel>::Subpixel>>> +use crate::TypedOutputFormat; + +pub fn rescale<T: GenericImage>(image: &T, factor: f32) -> anyhow::Result<TypedOutputFormat<T>> where T::Pixel: 'static, <T::Pixel as Pixel>::Subpixel: 'static, diff --git a/src/format.rs b/src/format.rs index b0274e707f9225689eb438b0a246ba7509f2db29..d671d4e94728028ddca000d9922978b9c0d4e5d9 100644 --- a/src/format.rs +++ b/src/format.rs @@ -10,39 +10,33 @@ use thiserror::Error; Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ArgEnum, Debug, Serialize, Deserialize, Default, )] pub enum PaletteFormat { - TXT, + Txt, #[default] - PNG, + Png, } -// impl Default for PaletteFormat { -// fn default() -> Self { -// Self::PNG -// } -// } - #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ArgEnum, Debug)] pub enum Format { - PNG, - JPG, - GIF, - ICO, - TGA, - TIFF, - BMP, + Png, + Jpg, + Gif, + Ico, + Tga, + Tiff, + Bmp, } impl Format { pub fn as_image_format(&self) -> ImageFormat { use Format::*; match self { - PNG => ImageFormat::Png, - JPG => ImageFormat::Jpeg, - GIF => ImageFormat::Gif, - ICO => ImageFormat::Ico, - TGA => ImageFormat::Tga, - TIFF => ImageFormat::Tiff, - BMP => ImageFormat::Bmp, + Png => ImageFormat::Png, + Jpg => ImageFormat::Jpeg, + Gif => ImageFormat::Gif, + Ico => ImageFormat::Ico, + Tga => ImageFormat::Tga, + Tiff => ImageFormat::Tiff, + Bmp => ImageFormat::Bmp, } } } diff --git a/src/main.rs b/src/main.rs index 2dd3fb8d4dd7be7db6c2ff0c22c27594f97096a2..71f8d0141448d571881ea45d2dc0badb402fe386 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,6 +25,9 @@ struct SpriteData<'a, T: GenericImage> { } pub type OutputFormat = image::ImageBuffer<Rgba<u8>, Vec<u8>>; +#[allow(type_alias_bounds)] +pub type TypedOutputFormat<T: image::GenericImage> = + image::ImageBuffer<T::Pixel, Vec<<T::Pixel as image::Pixel>::Subpixel>>; fn main() -> anyhow::Result<(), anyhow::Error> { env_logger::Builder::from_env("LOG_LEVEL").init();