pub fn slugify_string(input: &str) -> String {
let lowered = input.trim().to_ascii_lowercase();
let stripped = lowered.strip_suffix(".git").unwrap_or(&lowered);
let mut out = String::with_capacity(stripped.len());
let mut prev_hyphen = false;
for c in stripped.chars() {
let next = match c {
'a'..='z' | '0'..='9' => Some(c),
'_' | '-' | ' ' | '\t' => Some('-'),
_ => None,
};
if let Some(c) = next {
if c == '-' {
if !prev_hyphen && !out.is_empty() {
out.push('-');
prev_hyphen = true;
}
} else {
out.push(c);
prev_hyphen = false;
}
}
}
while out.ends_with('-') {
out.pop();
}
out
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn slug_derivation_cases() {
assert_eq!(slugify_string("trusty-tools"), "trusty-tools");
assert_eq!(slugify_string("Trusty_Tools"), "trusty-tools");
assert_eq!(slugify_string("trusty tools"), "trusty-tools");
assert_eq!(slugify_string(" trusty tools "), "trusty-tools");
assert_eq!(slugify_string("trusty-tools.git"), "trusty-tools");
assert_eq!(slugify_string("trusty/tools!"), "trustytools");
assert_eq!(slugify_string("foo--bar"), "foo-bar");
assert_eq!(slugify_string("My_Cool Project"), "my-cool-project");
assert_eq!(slugify_string(" --weird__name-- "), "weird-name");
assert_eq!(slugify_string("!!!"), "");
assert_eq!(slugify_string("漢字"), "");
}
}