pub mod bidx; pub mod build; pub mod hash; pub mod write; pub use build::build; pub use write::write; use std::path::{Path, PathBuf}; /// Information about a chunk for index file #[derive(Debug, Clone)] pub struct ChunkInfo { /// Index of the chunk in the file pub index: usize, /// Hash of the chunk (hex string) pub hash: String, } /// Calculate the storage path of a chunk file based on its hash value pub fn get_chunk_path(storage_dir: &Path, hash_hex: &str) -> PathBuf { let first_slice = &hash_hex[0..2]; storage_dir.join(first_slice).join(hash_hex) } /// Calculate the storage path of a chunk file based on its hash byte array pub fn get_chunk_path_from_bytes(storage_dir: &Path, hash_bytes: &[u8; 32]) -> PathBuf { let hash_hex = hex::encode(hash_bytes); get_chunk_path(storage_dir, &hash_hex) } /// Generate a unique file path, adding a numeric suffix if the file already exists pub fn generate_unique_path(output_dir: &Path, desired_filename: &str) -> PathBuf { let desired_path = output_dir.join(desired_filename); let mut candidate = desired_path.clone(); let mut counter = 1; while candidate.exists() { let path_buf = PathBuf::from(desired_filename); if let Some(stem) = path_buf.file_stem() { if let Some(ext) = path_buf.extension() { let ext_str = ext.to_string_lossy(); let new_name = if ext_str.is_empty() { format!("{}_{}", stem.to_string_lossy(), counter) } else { format!("{}.{}_{}", stem.to_string_lossy(), ext_str, counter) }; candidate = output_dir.join(new_name); } else { candidate = output_dir.join(format!("{}_{}", stem.to_string_lossy(), counter)); } } else { candidate = output_dir.join(format!("{}_{}", desired_filename, counter)); } counter += 1; } candidate }