image_optimizer/cli/
cli_args.rs1use clap::Parser;
2use std::path::PathBuf;
3
4#[derive(Parser)]
19#[command(name = "image-optimizer")]
20#[command(about = "CLI tool for optimizing images (JPEG, PNG, WebP, SVG)")]
21#[command(long_about = None)]
22#[command(version = env!("CARGO_PKG_VERSION"))]
23#[allow(clippy::struct_excessive_bools)]
24pub struct Cli {
25 #[arg(short, long)]
27 pub input: Option<PathBuf>,
28
29 #[arg(short, long)]
31 pub output: Option<PathBuf>,
32
33 #[arg(long)]
35 pub backup: bool,
36
37 #[arg(long)]
39 pub webp_lossless: bool,
40
41 #[arg(long, default_value = "85")]
43 pub jpeg_quality: u8,
44
45 #[arg(short, long)]
47 pub recursive: bool,
48
49 #[arg(long)]
51 pub max_size: Option<u32>,
52
53 #[arg(long, default_value = "2")]
55 pub png_optimization_level: String,
56
57 #[arg(long, default_value = "15")]
59 pub zopfli_iterations: std::num::NonZeroU8,
60
61 #[arg(long)]
62 pub no_zopfli: bool,
63
64 #[arg(long)]
65 pub no_parallel: bool,
66
67 #[arg(long)]
69 pub update: bool,
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75 use clap::CommandFactory;
76
77 #[test]
78 fn test_cli_defaults() {
79 let cli = Cli::parse_from(["image-optimizer"]);
80 assert_eq!(cli.input, None);
81 assert_eq!(cli.output, None);
82 assert!(!cli.backup);
83 assert!(!cli.webp_lossless);
84 assert_eq!(cli.jpeg_quality, 85);
85 assert!(!cli.recursive);
86 assert_eq!(cli.max_size, None);
87 assert_eq!(cli.png_optimization_level, "2");
88 assert_eq!(cli.zopfli_iterations.get(), 15);
89 assert!(!cli.update);
90 }
91
92 #[test]
93 fn test_cli_with_input() {
94 let cli = Cli::parse_from(["image-optimizer", "-i", "/path/to/images"]);
95 assert_eq!(cli.input, Some(PathBuf::from("/path/to/images")));
96 }
97
98 #[test]
99 fn test_cli_with_all_flags() {
100 let cli = Cli::parse_from([
101 "image-optimizer",
102 "-i",
103 "/input",
104 "-o",
105 "/output",
106 "--backup",
107 "--webp-lossless",
108 "--jpeg-quality",
109 "90",
110 "--recursive",
111 "--max-size",
112 "1024",
113 "--png-optimization-level",
114 "max",
115 "--zopfli-iterations",
116 "25",
117 "--update",
118 ]);
119
120 assert_eq!(cli.input, Some(PathBuf::from("/input")));
121 assert_eq!(cli.output, Some(PathBuf::from("/output")));
122 assert!(cli.backup);
123 assert!(cli.webp_lossless);
124 assert_eq!(cli.jpeg_quality, 90);
125 assert!(cli.recursive);
126 assert_eq!(cli.max_size, Some(1024));
127 assert_eq!(cli.png_optimization_level, "max");
128 assert_eq!(cli.zopfli_iterations.get(), 25);
129 assert!(cli.update);
130 assert!(!cli.no_zopfli);
131 assert!(!cli.no_parallel);
132 }
133
134 #[test]
135 fn test_cli_quality_bounds() {
136 let cli = Cli::parse_from(["image-optimizer", "--jpeg-quality", "1"]);
137 assert_eq!(cli.jpeg_quality, 1);
138
139 let cli = Cli::parse_from(["image-optimizer", "--jpeg-quality", "100"]);
140 assert_eq!(cli.jpeg_quality, 100);
141 }
142
143 #[test]
144 fn test_cli_help_generation() {
145 let mut cmd = Cli::command();
146 let help = cmd.render_help();
147 assert!(help.to_string().contains("CLI tool for optimizing images"));
148 }
149}