use std::path::{Path, PathBuf};
pub fn client_file_name(client_path: &str) -> String {
let name = client_path
.trim()
.trim_end_matches(['/', '\\'])
.rsplit(['/', '\\'])
.next()
.unwrap_or("")
.trim();
if name.is_empty() || name == "." || name == ".." {
"dropped-file".to_string()
} else {
name.to_string()
}
}
pub fn landing_path(
dir: &Path,
client_path: &str,
stamp: u128,
taken: impl Fn(&Path) -> bool,
) -> PathBuf {
let name = client_file_name(client_path);
let plain = dir.join(&name);
if !taken(&plain) {
return plain;
}
let as_path = Path::new(&name);
let stem = as_path
.file_stem()
.map(|s| s.to_string_lossy().to_string())
.filter(|s| !s.is_empty())
.unwrap_or_else(|| name.clone());
let ext = as_path
.extension()
.map(|e| format!(".{}", e.to_string_lossy()))
.unwrap_or_default();
dir.join(format!("{stem}-{stamp}{ext}"))
}
pub fn pulled_notice(name: &str, landed: &str, bytes: usize) -> String {
format!(
"Pulled {name} ({}) from your machine to {landed}",
human_size(bytes)
)
}
pub fn human_size(bytes: usize) -> String {
const KB: f64 = 1024.0;
let b = bytes as f64;
if b < KB {
format!("{bytes} B")
} else if b < KB * KB {
format!("{:.1} KB", b / KB)
} else {
format!("{:.1} MB", b / (KB * KB))
}
}