Slug an identity display name into a human-key author handle. Lowercases, converts whitespace runs to single `-`, drops characters other than `[a-z0-9-]`, and collapses/trims hyphens. Interior hyphens are kept — the human key separates fields with `::`, so `lee-faus` stays unambiguous. Falls back to `unknown` when the result would be empty.
(name: &str)
| 951 | /// the human key separates fields with `::`, so `lee-faus` stays unambiguous. |
| 952 | /// Falls back to `unknown` when the result would be empty. |
| 953 | pub(crate) fn slug_author(name: &str) -> String { |
| 954 | let mut out = String::new(); |
| 955 | let mut last_dash = false; |
| 956 | for ch in name.trim().chars() { |
| 957 | let c = ch.to_ascii_lowercase(); |
| 958 | if c.is_ascii_alphanumeric() { |
| 959 | out.push(c); |
| 960 | last_dash = false; |
| 961 | } else if (c.is_whitespace() || c == '-' || c == '_') && !out.is_empty() && !last_dash { |
| 962 | out.push('-'); |
| 963 | last_dash = true; |
| 964 | } |
| 965 | // any other char is dropped |
| 966 | } |
| 967 | while out.ends_with('-') { |
| 968 | out.pop(); |
| 969 | } |
| 970 | if out.is_empty() { |
| 971 | "unknown".to_string() |
| 972 | } else { |
| 973 | out |
| 974 | } |
| 975 | } |
| 976 | |
| 977 | fn remove_empty_dirs_up_to( |
| 978 | mut dir: &std::path::Path, |
no test coverage detected