use std::path::Path;
pub(crate) const HUGE_CUTOFF_BYTES: u64 = 1_000_000;
pub(crate) fn estimate(manifest_dir: &Path) -> u64 {
manifest_dir_rs_bytes_clamped(manifest_dir, HUGE_CUTOFF_BYTES)
}
fn manifest_dir_rs_bytes_clamped(manifest_dir: &Path, cap: u64) -> u64 {
let mut total: u64 = 0;
let walker = walkdir::WalkDir::new(manifest_dir)
.follow_links(false)
.into_iter()
.filter_entry(|e| e.file_name() != "target");
for entry in walker {
let Ok(entry) = entry else { continue };
if !entry.file_type().is_file() {
continue;
}
if entry.path().extension().is_none_or(|x| x != "rs") {
continue;
}
if let Ok(m) = entry.metadata() {
total = total.saturating_add(m.len());
if total >= cap {
return cap;
}
}
}
total
}
#[cfg(test)]
mod tests {
#![allow(clippy::unwrap_used)]
use super::{HUGE_CUTOFF_BYTES, estimate, manifest_dir_rs_bytes_clamped};
use std::path::PathBuf;
fn unique_tmp(prefix: &str) -> PathBuf {
std::env::temp_dir().join(format!("{prefix}-{}", std::process::id()))
}
#[test]
fn estimate_sums_rs_bytes_and_ignores_other_files() {
let dir = unique_tmp("ff-size-sum");
let _ = std::fs::remove_dir_all(&dir);
std::fs::create_dir_all(&dir).unwrap();
std::fs::write(dir.join("a.rs"), vec![b'x'; 100]).unwrap();
std::fs::write(dir.join("b.rs"), vec![b'y'; 50]).unwrap();
std::fs::write(dir.join("notes.txt"), vec![b'z'; 9999]).unwrap();
let bytes = estimate(&dir);
assert_eq!(bytes, 150, "only the two .rs files count");
assert!(bytes < HUGE_CUTOFF_BYTES);
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
fn clamping_returns_the_cap_verbatim_once_reached() {
let dir = unique_tmp("ff-size-clamp");
let _ = std::fs::remove_dir_all(&dir);
std::fs::create_dir_all(&dir).unwrap();
std::fs::write(dir.join("a.rs"), vec![b'x'; 1000]).unwrap();
std::fs::write(dir.join("b.rs"), vec![b'y'; 1000]).unwrap();
assert_eq!(manifest_dir_rs_bytes_clamped(&dir, 500), 500);
assert_eq!(manifest_dir_rs_bytes_clamped(&dir, 10_000), 2000);
let _ = std::fs::remove_dir_all(&dir);
}
}