Quality and verbose validation

This commit is contained in:
Matteo Paonessa 2025-02-17 20:27:57 +01:00
parent c1d077cf39
commit 4c164aa9cf
4 changed files with 45 additions and 32 deletions

17
Cargo.lock generated
View File

@ -203,7 +203,7 @@ dependencies = [
"image",
"imagesize",
"indicatif",
"infer",
"infer 0.19.0",
"kamadak-exif",
"libcaesium",
"rayon",
@ -629,6 +629,15 @@ dependencies = [
"cfb",
]
[[package]]
name = "infer"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7"
dependencies = [
"cfb",
]
[[package]]
name = "interpolate_name"
version = "0.2.4"
@ -703,16 +712,16 @@ checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]]
name = "libcaesium"
version = "0.17.1"
version = "0.17.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8bccd9f46ed0d4fc35e5d20a073a0861f24224320031a3405872243a6370001"
checksum = "01758171300d6c9666e33e9dcac3fe06650884493d221aab06c6a93c671aa800"
dependencies = [
"bytes",
"gifsicle",
"image",
"imagequant",
"img-parts",
"infer",
"infer 0.16.0",
"kamadak-exif",
"libc",
"lodepng",

View File

@ -17,12 +17,12 @@ repository = "https://github.com/Lymphatus/caesium-clt"
[dependencies]
indicatif = { version = "0.17", features = ["rayon"] }
walkdir = "2.5"
infer = "0.16"
infer = "0.19"
rayon = "1.10"
human_bytes = { version = "0.4", default-features = false }
kamadak-exif = "0.6"
imagesize = "0.13"
libcaesium = "0.17.1"
libcaesium = "0.17.2"
clap = { version = "4.5", features = ["derive"] }
[dev-dependencies]

View File

@ -1,6 +1,5 @@
use crate::compressor::{start_compression, CompressionOptions, CompressionResult, CompressionStatus};
use crate::options::VerboseLevel::{All, Progress, Quiet};
use crate::options::{CommandLineArgs, VerboseLevel};
use crate::options::CommandLineArgs;
use crate::scan_files::scan_files;
use clap::Parser;
use human_bytes::human_bytes;
@ -27,8 +26,8 @@ fn main() {
.build_global()
.unwrap_or_default();
let quiet = args.quiet || args.verbose == Quiet;
let verbose = if quiet { Quiet } else { args.verbose };
let quiet = args.quiet || args.verbose == 0;
let verbose = if quiet { 0 } else { args.verbose };
let (base_path, input_files) = scan_files(&args.files, args.recursive, quiet);
let total_files = input_files.len();
@ -39,7 +38,7 @@ fn main() {
write_recap_message(&compression_results, verbose);
}
fn write_recap_message(compression_results: &[CompressionResult], verbose: VerboseLevel) {
fn write_recap_message(compression_results: &[CompressionResult], verbose: u8) {
let mut total_original_size = 0;
let mut total_compressed_size = 0;
let total_files = compression_results.len();
@ -56,8 +55,8 @@ fn write_recap_message(compression_results: &[CompressionResult], verbose: Verbo
_ => total_success += 1,
}
if verbose > Progress {
if verbose < All && matches!(result.status, CompressionStatus::Success) {
if verbose > 1 {
if verbose < 3 && matches!(result.status, CompressionStatus::Success) {
continue;
}
println!(
@ -80,7 +79,7 @@ fn write_recap_message(compression_results: &[CompressionResult], verbose: Verbo
let total_saved = total_original_size as f64 - total_compressed_size as f64;
let total_saved_percent = total_saved / total_original_size as f64 * 100.0;
if verbose > Quiet {
if verbose > 0 {
println!(
"Compressed {} files ({} success, {} skipped, {} errors)\n{} -> {} [Saved {} ({:.2}%)]",
total_files,
@ -103,9 +102,9 @@ fn get_parallelism_count(requested_threads: u32, available_threads: usize) -> us
}
}
fn setup_progress_bar(len: usize, verbose: VerboseLevel) -> ProgressBar {
fn setup_progress_bar(len: usize, verbose: u8) -> ProgressBar {
let progress_bar = ProgressBar::new(len as u64);
if verbose == Quiet {
if verbose == 0 {
progress_bar.set_draw_target(ProgressDrawTarget::hidden());
} else {
progress_bar.set_draw_target(ProgressDrawTarget::stdout());

View File

@ -19,19 +19,6 @@ pub enum OutputFormat {
Tiff,
Original,
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Debug)]
pub enum VerboseLevel {
/// Suppress all output
Quiet = 0,
/// Show only progress and final results
Progress = 1,
/// Show also skipped and error messages
WarningsAndErrors = 2,
/// Print all
All = 3,
}
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
pub struct CommandLineArgs {
@ -93,8 +80,8 @@ pub struct CommandLineArgs {
pub quiet: bool,
/// select how much output you want to see
#[arg(long, value_enum, default_value = "progress", group = "verbosity")]
pub verbose: VerboseLevel,
#[arg(long, default_value = "1", group = "verbosity", value_parser = verbose_validator)]
pub verbose: u8,
pub files: Vec<String>,
}
@ -103,7 +90,7 @@ pub struct CommandLineArgs {
#[group(required = true, multiple = false)]
pub struct Compression {
/// sets output file quality between [0-100]
#[arg(short, long)]
#[arg(short, long, value_parser = quality_validator)]
pub quality: Option<u32>,
/// perform lossless compression
@ -146,3 +133,21 @@ pub struct OutputDestination {
#[arg(long, default_value = "false", group = "output_destination")]
pub same_folder_as_input: bool,
}
fn quality_validator(val: &str) -> Result<u32, String> {
let value: u32 = val.parse().map_err(|_| format!("`{}` is not a valid number", val))?;
if value > 100 {
Err(format!("Quality must be between 0 and 100, but found `{}`", value))
} else {
Ok(value)
}
}
fn verbose_validator(val: &str) -> Result<u8, String> {
let value: u8 = val.parse().map_err(|_| format!("`{}` is not a valid number", val))?;
if value > 3 {
Err(format!("Verbosity must be between 0 and 3, but found `{}`", value))
} else {
Ok(value)
}
}