bendn 2023-10-31
parent 97ab261 · commit ff4acc1
-rw-r--r--Cargo.toml1
-rw-r--r--src/main.rs65
2 files changed, 52 insertions, 14 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 5fd5968..82b0f7b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,4 +6,5 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+comat = "0.1.3"
fimg = { version = "0.4.22", features = ["save"], default-features = false }
diff --git a/src/main.rs b/src/main.rs
index 2318b7a..e8dedcb 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,21 +1,58 @@
+use comat::comat;
+use fimg::{DynImage, Image};
use std::process::ExitCode;
fn main() -> ExitCode {
+ macro_rules! fail {
+ () => {
+ fail!("<in> <out> (un <ch> <w>x<h>)")
+ };
+ ($usage:literal) => {{
+ eprintln!(concat!("usage: hew ", comat!($usage)));
+ return ExitCode::FAILURE;
+ }};
+ }
let mut args = std::env::args().skip(1);
- let Some(input) = args.next() else {
- eprintln!("usage: hew <in> <out>");
- return ExitCode::FAILURE;
- };
- let Some(output) = args.next() else {
- eprintln!("usage: hew <in> <out>");
- return ExitCode::FAILURE;
- };
+ let Some(input) = args.next() else { fail!() };
+ let Some(output) = args.next() else { fail!() };
+ match args.next().as_deref() {
+ Some("un") => {
+ let Some(channels) = args.next() else {
+ fail!(".. un {bold_red}channels{reset} ..")
+ };
+ let Some(size) = args.next() else {
+ fail!(".. un <ch> <width>x<height>")
+ };
- let img = fimg::DynImage::open(input);
- println!("{}x{}", img.width(), img.height());
- match std::fs::write(output, img.bytes()) {
- Ok(_) => return ExitCode::SUCCESS,
- Err(_) => eprintln!("usage: hew <in> <valid path output>"),
+ let Some((w, h)) = size.split_once('x') else {
+ fail!(".. un <ch> <w>{bold_red}x{reset}<h>")
+ };
+ let Ok(w) = w.parse() else {
+ fail!(".. un <ch> <width: valid number>x<h>")
+ };
+ let Ok(h) = h.parse() else {
+ fail!(".. un <ch> <w>x<h: valid number>")
+ };
+ let Ok(bytes) = std::fs::read(input) else {
+ fail!("<input: valid path>")
+ };
+ match &*channels {
+ "1" => Image::<_, 1>::build(w, h).buf(bytes).save(output),
+ "2" => Image::<_, 2>::build(w, h).buf(bytes).save(output),
+ "3" => Image::<_, 3>::build(w, h).buf(bytes).save(output),
+ "4" => Image::<_, 4>::build(w, h).buf(bytes).save(output),
+ _ => fail!(".. un <ch: {bold_red}1, 2, 3, 4{reset}>"),
+ };
+ }
+ _ => {
+ let img = DynImage::open(input);
+ println!("{}x{}", img.width(), img.height());
+ match std::fs::write(output, img.bytes()) {
+ Ok(_) => return ExitCode::SUCCESS,
+ Err(_) => fail!("<in> <output: valid path>"),
+ }
+ }
}
- ExitCode::FAILURE
+
+ ExitCode::SUCCESS
}