mod cli;
use std::fs;
use std::path::Path;
use anyhow::{Context as _, Result, bail};
use clap::Parser;
use tracing_subscriber::EnvFilter;
use compress_pdf::compress::{Verify, compress};
use compress_pdf::config::Config;
use crate::cli::{Cli, VerifyArg};
fn main() -> Result<()> {
let cli = Cli::parse();
init_logging(cli.verbose);
let config = cli.config();
tracing::debug!(?config, "effective configuration");
if let [input] = cli.inputs.as_slice() {
return compress_one(&cli, &config, input);
}
let mut failed = 0;
for input in &cli.inputs {
println!("== {}", input.display());
if let Err(e) = compress_one(&cli, &config, input) {
eprintln!("error: {}: {e:#}", input.display());
failed += 1;
}
}
if failed > 0 {
bail!("{failed} of {} files failed", cli.inputs.len());
}
Ok(())
}
fn compress_one(cli: &Cli, config: &Config, input_path: &Path) -> Result<()> {
let output = cli.output_path(input_path);
let input =
fs::read(input_path).with_context(|| format!("reading {}", input_path.display()))?;
let verify = match cli.verify {
VerifyArg::Render => Verify::Render {
preset: cli.preset(),
strict: cli.strict,
},
VerifyArg::Structural => Verify::Structural,
};
let done = match compress(&input, config, verify) {
Ok(compressed) => compressed,
Err(rejected) => {
print!("{}", rejected.report);
return Err(rejected.into());
}
};
let (buf, report) = (done.output, done.report);
if cli.dry_run {
print!("{report}");
return Ok(());
}
if let Some(dir) = output.parent().filter(|d| !d.as_os_str().is_empty()) {
fs::create_dir_all(dir).with_context(|| format!("creating {}", dir.display()))?;
}
fs::write(&output, &buf).with_context(|| format!("writing {}", output.display()))?;
print!("{report}");
println!("wrote {}", output.display());
Ok(())
}
fn init_logging(verbosity: u8) {
let (level, lopdf) = match verbosity {
0 => ("warn", "error"),
1 => ("info", "warn"),
2 => ("debug", "info"),
_ => ("trace", "trace"),
};
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new(format!("{level},lopdf={lopdf}")));
tracing_subscriber::fmt()
.with_env_filter(filter)
.with_target(false)
.with_writer(std::io::stderr)
.init();
}