use std::path::PathBuf;
use anyhow::Result;
use clap::{Parser, ValueEnum};
use crazy_deduper::{Deduper, HashingAlgorithm, Hydrator};
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Cli {
source: PathBuf,
target: PathBuf,
#[arg(long)]
cache_file: Vec<PathBuf>,
#[arg(long, value_enum, default_value_t = HashingAlgorithmArgument::SHA1)]
hashing_algorithm: HashingAlgorithmArgument,
#[arg(long)]
same_file_system: bool,
#[arg(long, default_value_t = 0)]
declutter_levels: usize,
#[arg(long, short, visible_alias = "hydrate")]
decode: bool,
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, ValueEnum)]
pub enum HashingAlgorithmArgument {
MD5,
SHA1,
SHA256,
SHA512,
}
impl From<HashingAlgorithmArgument> for HashingAlgorithm {
fn from(value: HashingAlgorithmArgument) -> Self {
match value {
HashingAlgorithmArgument::MD5 => HashingAlgorithm::MD5,
HashingAlgorithmArgument::SHA1 => HashingAlgorithm::SHA1,
HashingAlgorithmArgument::SHA256 => HashingAlgorithm::SHA256,
HashingAlgorithmArgument::SHA512 => HashingAlgorithm::SHA512,
}
}
}
fn main() -> Result<()> {
let args = Cli::parse();
let source = args.source;
let target = args.target;
let cache_files = args.cache_file;
let same_file_system = args.same_file_system;
let declutter_levels = args.declutter_levels;
if !args.decode {
let mut deduper = Deduper::new(
source,
cache_files,
args.hashing_algorithm.into(),
same_file_system,
);
deduper.write_chunks(target, declutter_levels)?;
deduper.write_cache();
} else {
let hydrator = Hydrator::new(source, cache_files);
hydrator.restore_files(target, declutter_levels);
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn verify_cli() {
use clap::CommandFactory;
Cli::command().debug_assert()
}
}