diff --git a/Cargo.lock b/Cargo.lock index 1be020ed..d88ffe4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -309,6 +309,12 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itoa" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010" + [[package]] name = "libc" version = "0.2.175" @@ -346,6 +352,12 @@ version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -398,6 +410,7 @@ dependencies = [ "rayon", "rgb", "rustc-hash", + "serde_json", "zopfli", ] @@ -426,6 +439,15 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "proc-macro2" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +dependencies = [ + "unicode-ident", +] + [[package]] name = "pxfm" version = "0.1.24" @@ -435,6 +457,15 @@ dependencies = [ "num-traits", ] +[[package]] +name = "quote" +version = "1.0.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +dependencies = [ + "proc-macro2", +] + [[package]] name = "radium" version = "0.7.0" @@ -489,6 +520,48 @@ dependencies = [ "windows-sys 0.61.0", ] +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6af14725505314343e673e9ecb7cd7e8a36aa9791eb936235a3567cc31447ae4" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + [[package]] name = "shlex" version = "1.3.0" @@ -507,6 +580,17 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "syn" +version = "2.0.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "tap" version = "1.0.1" @@ -523,6 +607,12 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + [[package]] name = "utf8parse" version = "0.2.2" @@ -633,6 +723,12 @@ dependencies = [ "tap", ] +[[package]] +name = "zmij" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4af59da1029247450b54ba43e0b62c8e376582464bbe5504dd525fe521e7e8fd" + [[package]] name = "zopfli" version = "0.8.3" diff --git a/Cargo.toml b/Cargo.toml index 9c333ecc..091c5493 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -79,6 +79,9 @@ default-features = false features = ["png"] version = "0.25.9" +[dev-dependencies] +serde_json = "1.0.147" + [features] binary = ["dep:clap", "dep:glob", "dep:env_logger", "dep:parse-size"] default = ["binary", "parallel", "zopfli"] diff --git a/tests/files/json.png b/tests/files/json.png new file mode 100644 index 00000000..7c7f12ce Binary files /dev/null and b/tests/files/json.png differ diff --git a/tests/flags.rs b/tests/flags.rs index 63646c9d..6b3fdda9 100644 --- a/tests/flags.rs +++ b/tests/flags.rs @@ -1,10 +1,12 @@ use std::{ fs::remove_file, path::{Path, PathBuf}, + process::Command, }; use indexmap::indexset; use oxipng::{internal_tests::*, *}; +use serde_json::Value; const GRAY: u8 = 0; const RGB: u8 = 2; @@ -662,3 +664,39 @@ fn zopfli_mode() { BitDepth::Eight, ); } +#[test] +fn json_success() { + let path = "tests/files/json.png"; + let output = Command::new(env!("CARGO_BIN_EXE_oxipng")) + .args(["--json", "--nx", "--nz", path]) + .output() + .expect("Failed to run executable"); + assert!(output.status.success()); + let stdout = String::from_utf8_lossy(&output.stdout); + let data: Value = serde_json::from_str(&stdout).expect("Failed to parse JSON"); + let result = &data["results"][0]; + assert_eq!(result["input"], path); + assert_eq!(result["status"], "success"); + assert_eq!(result["output"], path); + assert_eq!(result["insize"], result["outsize"]); +} + +#[test] +fn json_dry_run() { + let path = "tests/files/json.png"; + let path2 = "tests/files/escape chars \\ \" \n \t \r \x08 \x0c.png"; + let output = Command::new(env!("CARGO_BIN_EXE_oxipng")) + .args(["--json", "--dry-run", path, path2]) + .output() + .expect("Failed to run executable"); + assert!(output.status.success()); + let stdout = String::from_utf8_lossy(&output.stdout); + let data: Value = serde_json::from_str(&stdout).expect("Failed to parse JSON"); + let result = &data["results"][0]; + assert_eq!(result["input"], path); + assert_eq!(result["status"], "success"); + assert_eq!(result["output"], Value::Null); + let result2 = &data["results"][1]; + assert_eq!(result2["input"], path2); + assert_eq!(result2["status"], "error"); +}