use std::ffi::OsStr;
use crate::constants::{SKIP_DIR_NAMES, SKIP_FILE_NAMES};
pub fn friendly_size(size: u64) -> String {
const UNITS: [(&str, u64); 5] = [
("B", 1),
("KB", 1024),
("MB", 1024 * 1024),
("GB", 1024 * 1024 * 1024),
("TB", 1024 * 1024 * 1024 * 1024),
];
if size == 0 {
return "0B".to_string();
}
let mut value = size as f64;
let mut unit = "B";
for (label, threshold) in UNITS.iter().rev() {
if size >= *threshold {
value = size as f64 / *threshold as f64;
unit = label;
break;
}
}
format!("{:.2}{}", value, unit)
}
pub fn basename(path: &OsStr) -> String {
path.to_string_lossy().to_string()
}
pub fn should_skip_dir(name: &str) -> bool {
SKIP_DIR_NAMES
.iter()
.any(|item| item.eq_ignore_ascii_case(name))
}
pub fn should_skip_file(name: &str) -> bool {
SKIP_FILE_NAMES
.iter()
.any(|item| item.eq_ignore_ascii_case(name))
|| name.starts_with("._")
|| name.starts_with("Thumb_")
|| name.starts_with(".l-s-tmp-")
}
pub fn hex_upper(bytes: impl AsRef<[u8]>) -> String {
bytes
.as_ref()
.iter()
.map(|b| format!("{:02X}", b))
.collect::<String>()
}
#[cfg(test)]
mod tests {
use super::{friendly_size, should_skip_file};
#[test]
fn friendly_size_formats_units() {
assert_eq!(friendly_size(0), "0B");
assert_eq!(friendly_size(1), "1.00B");
assert_eq!(friendly_size(1024), "1.00KB");
assert_eq!(friendly_size(1024 * 1024), "1.00MB");
}
#[test]
fn should_skip_atomic_write_temp_files() {
assert!(should_skip_file(".l-s-tmp-123-456"));
}
}