use anyhow::Result;
use clap::{Parser, Subcommand};
use std::path::PathBuf;
use znippy_common::{VerifyReport, list_archive_contents, verify_archive_integrity};
use znippy_common::plugin::PluginRegistry;
use znippy_common::plugins::wasm_loader::WasmPlugin;
use znippy_compress::compress_dir;
use znippy_decompress::decompress_archive;
pub mod handlers;
#[derive(Parser)]
#[command(name = "znippy")]
#[command(about = "Znippy: fast archive format with per-file compression", long_about = None)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Compress {
#[arg(short, long)]
input: PathBuf,
#[arg(short, long)]
output: PathBuf,
#[arg(long)]
no_skip: bool,
#[arg(long, default_value = "rust")]
format: String,
#[arg(long)]
plugin: Option<PathBuf>,
#[arg(long, default_value_t = 1)]
plugin_type_id: i8,
},
Decompress {
#[arg(short, long)]
input: PathBuf,
#[arg(short, long)]
output: PathBuf,
},
List {
#[arg(short, long)]
input: PathBuf,
},
Verify {
#[arg(short, long)]
input: PathBuf,
},
Handlers,
Run {
format: String,
cmd: String,
args: Vec<String>,
},
}
pub fn run() -> Result<()> {
env_logger::init();
let cli = Cli::parse();
match cli.command {
Commands::Compress {
input,
output,
no_skip,
format,
plugin,
plugin_type_id,
} => {
let registry = match plugin {
Some(wasm_path) => {
let wp = WasmPlugin::load(&wasm_path.to_string_lossy(), "wasm-plugin", plugin_type_id)?;
PluginRegistry::with_plugin(Box::new(wp))
}
None => {
let handler = handlers::find_handler(&format)?;
println!("π Handler: {} (type_id {})", handler.meta().name, handler.type_id());
PluginRegistry::with_plugin(handler)
}
};
let report = compress_dir(&input, &output, no_skip, Some(®istry), None)?;
println!("\nβ
Komprimering klar:");
println!("π Totalt antal filer: {}", report.total_files);
println!("π Totalt antal chunks: {}", report.chunks);
println!("π Totalt antal kataloger: {}", report.total_dirs);
println!("π¦ Filer komprimerade: {}", report.compressed_files);
println!(
"π Filer ej komprimerade: {}",
report.uncompressed_files
);
println!("π₯ Totalt inlΓ€sta bytes: {}", report.total_bytes_in);
println!("π€ Totalt skrivna bytes: {}", report.total_bytes_out);
println!("π Bytes som komprimerades: {}", report.compressed_bytes);
println!(
"π Bytes ej komprimerade: {}",
report.uncompressed_bytes
);
println!(
"π Komprimeringsgrad: {:.2}%",
report.compression_ratio
);
}
Commands::Decompress { input, output } => {
let report: VerifyReport = decompress_archive(&input, &output)?;
println!("\nβ
Dekomprimering och verifiering klar:");
println!("π Totala filer: {}", report.total_files);
println!("π Verifierade filer: {}", report.verified_files);
println!("π₯ chunks: {}", report.chunks);
println!("β Korrupta filer: {}", report.corrupt_files);
println!("π₯ Totala bytes: {}", report.total_bytes);
println!("π€ Verifierade bytes: {}", report.verified_bytes);
println!("β οΈ Korrupta bytes: {}", report.corrupt_bytes);
}
Commands::List { input } => {
list_archive_contents(&input)?;
}
Commands::Verify { input } => {
let report: VerifyReport = verify_archive_integrity(&input)?;
println!("\nπ Verifiering klar:");
println!("π Totala filer: {}", report.total_files);
println!("π Verifierade filer: {}", report.verified_files);
println!("β Korrupta filer: {}", report.corrupt_files);
println!("π₯ Totala bytes: {}", report.total_bytes);
println!("π€ Verifierade bytes: {}", report.verified_bytes);
println!("β οΈ Korrupta bytes: {}", report.corrupt_bytes);
}
Commands::Handlers => {
handlers::print_catalog();
}
Commands::Run { format, cmd, args } => {
let handler = handlers::find_handler(&format)?;
handler.run_command(&cmd, &args)?;
}
}
Ok(())
}