From 910e779b09bec9c8426045b9581ef81b4006f5db Mon Sep 17 00:00:00 2001 From: Kornel Date: Mon, 23 Dec 2024 17:11:57 +0000 Subject: [PATCH] Use ExitCode in main --- src/main.rs | 58 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/src/main.rs b/src/main.rs index 2f8bbcca..5d73be32 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,8 @@ mod rayon; #[cfg(feature = "zopfli")] use std::num::NonZeroU8; -use std::{ffi::OsString, fs::DirBuilder, io::Write, path::PathBuf, process::exit, time::Duration}; +use std::process::ExitCode; +use std::{ffi::OsString, fs::DirBuilder, io::Write, path::PathBuf, time::Duration}; use clap::ArgMatches; mod cli; @@ -29,7 +30,7 @@ use rayon::prelude::*; use crate::cli::DISPLAY_CHUNKS; -fn main() { +fn main() -> ExitCode { let matches = cli::build_command() // Set the value parser for filters which isn't appropriate to do in the build_command function .mut_arg("filters", |arg| { @@ -43,15 +44,15 @@ fn main() { .get_matches_from(std::env::args()); if matches.get_flag("backup") { - eprintln!("The --backup flag is no longer supported. Please use --out or --dir to preserve your existing files."); - exit(1) + error!("The --backup flag is no longer supported. Please use --out or --dir to preserve your existing files."); + return ExitCode::FAILURE; } let (out_file, out_dir, opts) = match parse_opts_into_struct(&matches) { Ok(x) => x, Err(x) => { error!("{}", x); - exit(1) + return ExitCode::FAILURE; } }; @@ -75,28 +76,41 @@ fn main() { true, ); - let success = files.into_par_iter().filter(|(input, output)| { - match oxipng::optimize(input, output, &opts) { - // For optimizing single files, this will return the correct exit code always. - // For recursive optimization, the correct choice is a bit subjective. - // We're choosing to return a 0 exit code if ANY file in the set - // runs correctly. - // The reason for this is that recursion may pick up files that are not - // PNG files, and return an error for them. - // We don't really want to return an error code for those files. - Ok(_) => true, - Err(e) => { - error!("{}: {}", input, e); - false + let summary = files + .into_par_iter() + .map(|(input, output)| { + match oxipng::optimize(&input, &output, &opts) { + // For optimizing single files, this will return the correct exit code always. + // For recursive optimization, the correct choice is a bit subjective. + // We're choosing to return a 0 exit code if ANY file in the set + // runs correctly. + // The reason for this is that recursion may pick up files that are not + // PNG files, and return an error for them. + // We don't really want to return an error code for those files. + Ok(_) => OptimizationResult::Ok, + Err(e) => { + error!("{input}: {e}"); + OptimizationResult::Failed + } } - } - }); + }) + .min() + .unwrap_or(OptimizationResult::Skipped); - if success.count() == 0 { - exit(1); + match summary { + OptimizationResult::Ok => ExitCode::SUCCESS, + OptimizationResult::Failed => ExitCode::FAILURE, + OptimizationResult::Skipped => ExitCode::from(3), } } +#[derive(Eq, PartialEq, Ord, PartialOrd)] +enum OptimizationResult { + Ok, + Failed, + Skipped, +} + fn collect_files( files: Vec, out_dir: &Option,