diff --git a/src/fileinfo.rs b/src/fileinfo.rs index d5dd829..0457108 100644 --- a/src/fileinfo.rs +++ b/src/fileinfo.rs @@ -4,6 +4,7 @@ use std::cmp::Ordering; use std::fs::{self, Metadata}; use std::io::Read; use std::path::PathBuf; +use clap::ValueEnum; const BLOCK_SIZE: usize = 4096; @@ -13,6 +14,7 @@ pub enum HashMode { Partial, } +#[derive(Debug, Copy, Clone, ValueEnum)] pub enum HashAlgoEnum { Sha256, Blake3, diff --git a/src/lib.rs b/src/lib.rs index 4df51e2..a52658f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,7 +31,8 @@ enum ChannelPackage { pub fn deduplicate_dirs + Sync>( search_dirs: Vec

, ignore_dirs: Vec

, - min_size: u64) -> (Vec, Vec<(PathBuf, std::io::Error)>) { + min_size: u64, + hash_algo: HashAlgoEnum) -> (Vec, Vec<(PathBuf, std::io::Error)>) { let (sender, receiver) = channel(); let ignore_paths = ignore_dirs.iter().map(|x| x.as_ref().canonicalize().unwrap()).collect(); search_dirs @@ -56,7 +57,7 @@ pub fn deduplicate_dirs + Sync>( }); let complete_files: Vec = files_of_lengths .into_par_iter() - .map(|x| differentiate_and_consolidate(x.0, x.1)) + .map(|x| differentiate_and_consolidate(x.0, x.1, hash_algo)) .flatten() .collect(); (complete_files, errors) @@ -124,7 +125,7 @@ fn traverse_and_spawn(current_path: impl AsRef, ignore_dirs: &Vec } } -fn differentiate_and_consolidate(file_length: u64, mut files: Vec) -> Vec { +fn differentiate_and_consolidate(file_length: u64, mut files: Vec, hash_algo: HashAlgoEnum) -> Vec { if file_length == 0 || files.is_empty() { return files; } @@ -132,7 +133,7 @@ fn differentiate_and_consolidate(file_length: u64, mut files: Vec) -> 1 => return files, n if n > 1 => { files.par_iter_mut().for_each(|file_ref| { - let hash = file_ref.generate_hash(HashMode::Partial, HashAlgoEnum::Blake3); + let hash = file_ref.generate_hash(HashMode::Partial, hash_algo); file_ref.set_partial_hash(hash); }); if file_length <= 4096 { @@ -159,7 +160,7 @@ fn differentiate_and_consolidate(file_length: u64, mut files: Vec) -> .collect(); files.par_iter_mut().for_each(|x| { if dedupe_hashes.contains(&x.get_partial_hash()) { - let hash = x.generate_hash(HashMode::Full, HashAlgoEnum::Blake3); + let hash = x.generate_hash(HashMode::Full, hash_algo); x.set_full_hash(hash); } }); diff --git a/src/main.rs b/src/main.rs index 08aee4e..0140db9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use clap::{Parser, ValueEnum}; -use ddh::fileinfo::Fileinfo; +use ddh::fileinfo::{Fileinfo, HashAlgoEnum}; use rayon::prelude::*; use std::fs::{self}; use std::io::prelude::*; @@ -24,6 +24,9 @@ struct Args { /// Set output format #[arg(short('f'), long("format"), ignore_case(true), value_enum, num_args(0..=1), default_value_t = PrintFmt::Standard)] fmt: PrintFmt, + /// Set output format + #[arg(short('a'), long("hashalgo"), ignore_case(true), value_enum, num_args(0..=1), default_value_t = HashAlgoEnum::Blake3)] + hash: HashAlgoEnum, /// Directories to ignore (comma separated list) #[arg(short, long("ignore"), value_delimiter(','))] ignore_dirs: Vec, @@ -64,7 +67,7 @@ fn main() { let arguments = Args::parse(); let (complete_files, read_errors): (Vec, Vec<(_, _)>) = - ddh::deduplicate_dirs(arguments.directories, arguments.ignore_dirs, arguments.min_size); + ddh::deduplicate_dirs(arguments.directories, arguments.ignore_dirs, arguments.min_size, arguments.hash); let (shared_files, unique_files): (Vec<&Fileinfo>, Vec<&Fileinfo>) = complete_files .par_iter() .partition(|&x| x.get_paths().len() > 1);