use crate::cli::{args::HashArgs, config::load_xxhash_config, global::GlobalArgs};
use base_d::DictionaryRegistry;
use std::fs;
use std::io::{self, Read, Write};
pub fn handle(
args: HashArgs,
global: &GlobalArgs,
config: &DictionaryRegistry,
) -> Result<(), Box<dyn std::error::Error>> {
let hash_algo = base_d::HashAlgorithm::from_str(&args.algorithm)?;
let input_data = if let Some(file_path) = &args.file {
if global.max_size > 0 {
let metadata = fs::metadata(file_path)?;
let file_size = metadata.len() as usize;
if file_size > global.max_size {
if global.force {
if !global.quiet {
eprintln!(
"Warning: Processing large file ({} bytes, limit: {} bytes)",
file_size, global.max_size
);
}
} else {
return Err(format!(
"File size ({} bytes) exceeds limit ({} bytes). Use --force to process anyway.",
file_size, global.max_size
)
.into());
}
}
}
fs::read(file_path)?
} else {
let mut buffer = Vec::new();
io::stdin().read_to_end(&mut buffer)?;
if global.max_size > 0 && buffer.len() > global.max_size {
return Err(format!(
"Input size ({} bytes) exceeds maximum ({} bytes). Use --file with --force for large inputs.",
buffer.len(),
global.max_size
)
.into());
}
buffer
};
let xxhash_config = load_xxhash_config(args.seed, args.secret_stdin, config, Some(&hash_algo))?;
let hash_output = base_d::hash_with_config(&input_data, hash_algo, &xxhash_config);
if let Some(encode_dict) = &args.encode {
let dictionary = crate::cli::config::create_dictionary(config, encode_dict)?;
let encoded = base_d::encode(&hash_output, &dictionary);
println!("{}", encoded);
} else if global.raw {
io::stdout().write_all(&hash_output)?;
} else {
println!("{}", hex::encode(&hash_output));
}
Ok(())
}