pub fn unique_name<'a>(base: &str, existing: impl Iterator<Item = &'a str>) -> String {
let taken: Vec<&str> = existing.collect();
if !taken.contains(&base) {
return base.to_string();
}
let mut counter = 2;
loop {
let candidate = format!("{base} {counter}");
if !taken.contains(&candidate.as_str()) {
return candidate;
}
counter += 1;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn unique_name_avoids_collisions() {
assert_eq!(unique_name("Mode", ["Default"].into_iter()), "Mode");
assert_eq!(unique_name("Mode", ["Mode"].into_iter()), "Mode 2");
assert_eq!(
unique_name("Mode", ["Mode", "Mode 2"].into_iter()),
"Mode 3"
);
}
}