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)
| 1262 | /// the human key separates fields with `::`, so `lee-faus` stays unambiguous. |
| 1263 | /// Falls back to `unknown` when the result would be empty. |
| 1264 | pub(crate) fn slug_author(name: &str) -> String { |
| 1265 | let mut out = String::new(); |
| 1266 | let mut last_dash = false; |
| 1267 | for ch in name.trim().chars() { |
| 1268 | let c = ch.to_ascii_lowercase(); |
| 1269 | if c.is_ascii_alphanumeric() { |
| 1270 | out.push(c); |
| 1271 | last_dash = false; |
| 1272 | } else if (c.is_whitespace() || c == '-' || c == '_') && !out.is_empty() && !last_dash { |
| 1273 | out.push('-'); |
| 1274 | last_dash = true; |
| 1275 | } |
| 1276 | // any other char is dropped |
| 1277 | } |
| 1278 | while out.ends_with('-') { |
| 1279 | out.pop(); |
| 1280 | } |
| 1281 | if out.is_empty() { |
| 1282 | "unknown".to_string() |
| 1283 | } else { |
| 1284 | out |
| 1285 | } |
| 1286 | } |
| 1287 | |
| 1288 | fn remove_empty_dirs_up_to( |
| 1289 | mut dir: &std::path::Path, |
no test coverage detected