- Migrate individual modules to independent crates - Refactor dependencies for improved modularity - Update build system and testing infrastructure - Update documentation to reflect new structure
124 lines
3.8 KiB
Rust
124 lines
3.8 KiB
Rust
pub fn name_fix(text: &str) -> String {
|
|
let mut result = String::with_capacity(text.len());
|
|
|
|
let mut last_was_underscore = false;
|
|
for c in text.chars() {
|
|
// Keep only ASCII characters
|
|
if c.is_ascii() {
|
|
// Replace specific characters with underscore
|
|
if c.is_whitespace()
|
|
|| c == ','
|
|
|| c == '-'
|
|
|| c == '"'
|
|
|| c == '\''
|
|
|| c == '#'
|
|
|| c == '!'
|
|
|| c == '('
|
|
|| c == ')'
|
|
|| c == '['
|
|
|| c == ']'
|
|
|| c == '='
|
|
|| c == '+'
|
|
|| c == '<'
|
|
|| c == '>'
|
|
|| c == '@'
|
|
|| c == '$'
|
|
|| c == '%'
|
|
|| c == '^'
|
|
|| c == '&'
|
|
|| c == '*'
|
|
{
|
|
// Only add underscore if the last character wasn't an underscore
|
|
if !last_was_underscore {
|
|
result.push('_');
|
|
last_was_underscore = true;
|
|
}
|
|
} else {
|
|
// Add the character as is (will be converted to lowercase later)
|
|
result.push(c);
|
|
last_was_underscore = false;
|
|
}
|
|
}
|
|
// Non-ASCII characters are simply skipped
|
|
}
|
|
|
|
// Convert to lowercase
|
|
return result.to_lowercase();
|
|
}
|
|
|
|
pub fn path_fix(text: &str) -> String {
|
|
// If path ends with '/', return as is
|
|
if text.ends_with('/') {
|
|
return text.to_string();
|
|
}
|
|
|
|
// Find the last '/' to extract the filename part
|
|
match text.rfind('/') {
|
|
Some(pos) => {
|
|
// Extract the path and filename parts
|
|
let path = &text[..=pos];
|
|
let filename = &text[pos + 1..];
|
|
|
|
// Apply name_fix to the filename part only
|
|
return format!("{}{}", path, name_fix(filename));
|
|
}
|
|
None => {
|
|
// No '/' found, so the entire text is a filename
|
|
return name_fix(text);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_name_fix() {
|
|
// Test ASCII conversion and special character replacement
|
|
assert_eq!(name_fix("Hello World"), "hello_world");
|
|
assert_eq!(name_fix("File-Name.txt"), "file_name.txt");
|
|
assert_eq!(name_fix("Test!@#$%^&*()"), "test_");
|
|
assert_eq!(name_fix("Space, Tab\t, Comma,"), "space_tab_comma_");
|
|
assert_eq!(name_fix("Quotes\"'"), "quotes_");
|
|
assert_eq!(name_fix("Brackets[]<>"), "brackets_");
|
|
assert_eq!(name_fix("Operators=+-"), "operators_");
|
|
|
|
// Test non-ASCII characters removal
|
|
assert_eq!(name_fix("Café"), "caf");
|
|
assert_eq!(name_fix("Résumé"), "rsum");
|
|
assert_eq!(name_fix("Über"), "ber");
|
|
|
|
// Test lowercase conversion
|
|
assert_eq!(name_fix("UPPERCASE"), "uppercase");
|
|
assert_eq!(name_fix("MixedCase"), "mixedcase");
|
|
}
|
|
|
|
#[test]
|
|
fn test_path_fix() {
|
|
// Test path ending with /
|
|
assert_eq!(path_fix("/path/to/directory/"), "/path/to/directory/");
|
|
|
|
// Test single filename
|
|
assert_eq!(path_fix("filename.txt"), "filename.txt");
|
|
assert_eq!(path_fix("UPPER-file.md"), "upper_file.md");
|
|
|
|
// Test path with filename
|
|
assert_eq!(path_fix("/path/to/File Name.txt"), "/path/to/file_name.txt");
|
|
assert_eq!(
|
|
path_fix("./relative/path/to/DOCUMENT-123.pdf"),
|
|
"./relative/path/to/document_123.pdf"
|
|
);
|
|
assert_eq!(
|
|
path_fix("/absolute/path/to/Résumé.doc"),
|
|
"/absolute/path/to/rsum.doc"
|
|
);
|
|
|
|
// Test path with special characters in filename
|
|
assert_eq!(
|
|
path_fix("/path/with/[special]<chars>.txt"),
|
|
"/path/with/_special_chars_.txt"
|
|
);
|
|
}
|
|
}
|