pub mod crypto;
pub mod validation;
pub mod time;
pub mod compression;
pub mod file_utils;
use std::path::Path;
pub fn is_text_file(path: &Path) -> bool {
if let Some(extension) = path.extension() {
let ext = extension.to_string_lossy().to_lowercase();
matches!(ext.as_str(),
"txt" | "md" | "rs" | "py" | "js" | "ts" | "html" | "css" | "json" |
"yaml" | "yml" | "toml" | "xml" | "csv" | "log" | "conf" | "cfg" |
"ini" | "sh" | "bat" | "ps1" | "sql" | "c" | "cpp" | "h" | "hpp" |
"java" | "kt" | "go" | "php" | "rb" | "swift" | "dart" | "scala" |
"clj" | "hs" | "elm" | "ex" | "exs" | "erl" | "pl" | "r" | "m" |
"dockerfile" | "gitignore" | "gitattributes" | "license" | "readme"
)
} else {
if let Some(filename) = path.file_name() {
let name = filename.to_string_lossy().to_lowercase();
matches!(name.as_str(),
"dockerfile" | "makefile" | "readme" | "license" | "changelog" |
"authors" | "contributors" | "copying" | "install" | "news" |
"todo" | "version" | "manifest"
)
} else {
false
}
}
}
pub fn format_file_size(size: u64) -> String {
const UNITS: &[&str] = &["B", "KB", "MB", "GB", "TB"];
let mut size = size as f64;
let mut unit_index = 0;
while size >= 1024.0 && unit_index < UNITS.len() - 1 {
size /= 1024.0;
unit_index += 1;
}
if unit_index == 0 {
format!("{} {}", size as u64, UNITS[unit_index])
} else {
format!("{:.1} {}", size, UNITS[unit_index])
}
}
pub fn sanitize_filename(filename: &str) -> String {
let sanitized = filename
.chars()
.filter(|c| !matches!(c, '/' | '\\' | ':' | '*' | '?' | '"' | '<' | '>' | '|'))
.collect::<String>()
.trim()
.to_string();
sanitized.trim_start_matches('.').to_string()
}
pub fn generate_random_string(length: usize) -> String {
use rand::{distributions::Alphanumeric, Rng};
rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(length)
.map(char::from)
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_format_file_size() {
assert_eq!(format_file_size(0), "0 B");
assert_eq!(format_file_size(1023), "1023 B");
assert_eq!(format_file_size(1024), "1.0 KB");
assert_eq!(format_file_size(1536), "1.5 KB");
assert_eq!(format_file_size(1048576), "1.0 MB");
}
#[test]
fn test_sanitize_filename() {
assert_eq!(sanitize_filename("test.txt"), "test.txt");
assert_eq!(sanitize_filename("../../../etc/passwd"), "etcpasswd");
assert_eq!(sanitize_filename("file<>name.txt"), "filename.txt");
}
#[test]
fn test_generate_random_string() {
let random = generate_random_string(10);
assert_eq!(random.len(), 10);
assert!(random.chars().all(|c| c.is_alphanumeric()));
}
}