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)
| 1078 | /// the human key separates fields with `::`, so `lee-faus` stays unambiguous. |
| 1079 | /// Falls back to `unknown` when the result would be empty. |
| 1080 | pub(crate) fn slug_author(name: &str) -> String { |
| 1081 | let mut out = String::new(); |
| 1082 | let mut last_dash = false; |
| 1083 | for ch in name.trim().chars() { |
| 1084 | let c = ch.to_ascii_lowercase(); |
| 1085 | if c.is_ascii_alphanumeric() { |
| 1086 | out.push(c); |
| 1087 | last_dash = false; |
| 1088 | } else if (c.is_whitespace() || c == '-' || c == '_') && !out.is_empty() && !last_dash { |
| 1089 | out.push('-'); |
| 1090 | last_dash = true; |
| 1091 | } |
| 1092 | // any other char is dropped |
| 1093 | } |
| 1094 | while out.ends_with('-') { |
| 1095 | out.pop(); |
| 1096 | } |
| 1097 | if out.is_empty() { |
| 1098 | "unknown".to_string() |
| 1099 | } else { |
| 1100 | out |
| 1101 | } |
| 1102 | } |
| 1103 | |
| 1104 | fn remove_empty_dirs_up_to( |
| 1105 | mut dir: &std::path::Path, |
no test coverage detected