use anyhow::Result;
use candle_coreml::clean_git_lfs_downloader::{
download_hf_model_clean, verify_download_completeness, CleanDownloadConfig,
};
use std::path::PathBuf;
fn main() -> Result<()> {
println!("🚀 Clean Git2 + HF Hub LFS Download Example");
println!("==========================================");
let cache_base = dirs::cache_dir()
.ok_or_else(|| anyhow::Error::msg("Cannot determine cache directory"))?
.join("candle-coreml-clean-examples");
std::fs::create_dir_all(&cache_base)?;
let model_id = "microsoft/DialoGPT-small";
println!("📦 Testing with model: {model_id}");
let config = CleanDownloadConfig::for_hf_model(model_id, &cache_base)
.with_verbose(true)
.with_keep_git(false);
println!("\n🔄 Starting clean download process...");
let model_path = download_hf_model_clean(&config)?;
println!("\n🔍 Verifying download completeness...");
let expected_files = [
"config.json",
"vocab.json",
"merges.txt",
"pytorch_model.bin", ];
verify_download_completeness(&model_path, &expected_files, true)?;
println!("\n✅ Clean download example completed successfully!");
println!("📁 Model downloaded to: {}", model_path.display());
println!("\n📂 Directory structure:");
show_directory_structure(&model_path, 0)?;
Ok(())
}
fn show_directory_structure(dir: &PathBuf, depth: usize) -> Result<()> {
if depth > 3 {
return Ok(());
}
let entries = std::fs::read_dir(dir)?;
let mut entries: Vec<_> = entries.collect::<Result<Vec<_>, _>>()?;
entries.sort_by_key(|e| e.file_name());
for entry in entries {
let path = entry.path();
let file_name = path.file_name().unwrap_or_default().to_string_lossy();
if file_name == ".git" {
continue;
}
let indent = " ".repeat(depth);
if path.is_dir() {
println!("{indent}📁 {file_name}/");
show_directory_structure(&path, depth + 1)?;
} else {
let metadata = std::fs::metadata(&path)?;
let size = metadata.len();
let size_str = if size < 1024 {
format!("{size} B")
} else if size < 1024 * 1024 {
format!("{:.1} KB", size as f64 / 1024.0)
} else if size < 1024 * 1024 * 1024 {
format!("{:.1} MB", size as f64 / (1024.0 * 1024.0))
} else {
format!("{:.1} GB", size as f64 / (1024.0 * 1024.0 * 1024.0))
};
println!("{indent}📄 {file_name} ({size_str})");
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_clean_download_config() {
let cache_base = std::env::temp_dir();
let config =
CleanDownloadConfig::for_hf_model("test/model", &cache_base).with_verbose(true);
assert_eq!(config.model_id, "test/model");
assert!(config.verbose);
assert!(!config.keep_git_dir);
}
}