const AVG_BYTES_PER_FILE: usize = 1536;
pub const fn estimate_output_size(total_files: usize) -> usize {
if total_files == 0 {
return 0;
}
let base_estimate = total_files.saturating_mul(AVG_BYTES_PER_FILE);
base_estimate.saturating_add(base_estimate / 3)
}
#[cfg(test)]
mod tests {
use super::*;
use proptest::prelude::*;
proptest! {
#[test]
fn prop_never_overflows(total_files in 0usize..1_000_000) {
let _result = estimate_output_size(total_files);
}
#[test]
fn prop_monotonic_increase(n in 1usize..10_000) {
let current = estimate_output_size(n);
let previous = estimate_output_size(n.saturating_sub(1));
assert!(
current >= previous,
"Estimate should be monotonically increasing: estimate({n}) = {current} should be >= estimate({}) = {previous}",
n - 1
);
}
#[test]
fn prop_buffer_factor_correct(total_files in 1usize..10_000) {
let estimate = estimate_output_size(total_files);
let expected_base = total_files.saturating_mul(AVG_BYTES_PER_FILE);
let expected_with_buffer = expected_base.saturating_add(expected_base / 3);
assert_eq!(
estimate, expected_with_buffer,
"Buffer calculation mismatch for {total_files} files: got {estimate}, expected {expected_with_buffer}"
);
}
#[test]
fn prop_zero_files_zero_estimate(_dummy in 0usize..100) {
assert_eq!(estimate_output_size(0), 0);
}
#[test]
fn prop_scales_linearly(n in 1usize..5_000) {
let single = estimate_output_size(n);
let doubled = estimate_output_size(n.saturating_mul(2));
let expected_doubled = single.saturating_mul(2);
let diff = doubled.abs_diff(expected_doubled);
let tolerance = expected_doubled / 100;
assert!(
diff <= tolerance,
"Linear scaling violated: estimate({n}) = {single}, estimate({})={doubled}, expected≈{expected_doubled}, diff={diff}",
n * 2
);
}
#[test]
fn prop_positive_for_nonzero(total_files in 1usize..100_000) {
let estimate = estimate_output_size(total_files);
assert!(
estimate > 0,
"Estimate should be positive for {total_files} files, got {estimate}"
);
}
}
#[test]
fn test_single_file_exact_value() {
assert_eq!(estimate_output_size(1), 2048);
}
#[test]
fn test_thousand_files_exact_value() {
assert_eq!(estimate_output_size(1000), 2_048_000);
}
#[test]
fn test_saturates_at_usize_max() {
assert_eq!(
estimate_output_size(usize::MAX),
usize::MAX,
"Should saturate to usize::MAX for extreme input"
);
}
#[test]
fn test_module_level_constant_value() {
assert_eq!(AVG_BYTES_PER_FILE, 1536);
}
}