gitbutler/crates/gitbutler-branch/src/dedup.rs
2024-07-14 21:32:55 +02:00

51 lines
1.6 KiB
Rust

pub fn dedup(existing: &[&str], new: &str) -> String {
dedup_fmt(existing, new, " ")
}
/// Makes sure that _new_ is not in _existing_ by adding a number to it.
/// the number is increased until the name is unique.
pub fn dedup_fmt(existing: &[&str], new: &str, separator: &str) -> String {
existing
.iter()
.filter_map(|x| {
x.strip_prefix(new)
.and_then(|x| x.strip_prefix(separator).or(Some("")))
.and_then(|x| {
if x.is_empty() {
Some(0_i32)
} else {
x.parse::<i32>().ok()
}
})
})
.max()
.map_or_else(
|| new.to_string(),
|x| format!("{new}{separator}{}", x + 1_i32),
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_dedup() {
for (existing, new, expected) in [
(vec!["bar", "baz"], "foo", "foo"),
(vec!["foo", "bar", "baz"], "foo", "foo 1"),
(vec!["foo", "foo 2"], "foo", "foo 3"),
(vec!["foo", "foo 1", "foo 2"], "foo", "foo 3"),
(vec!["foo", "foo 1", "foo 2"], "foo 1", "foo 1 1"),
(vec!["foo", "foo 1", "foo 2"], "foo 2", "foo 2 1"),
(vec!["foo", "foo 1", "foo 2"], "foo 3", "foo 3"),
(vec!["foo 2"], "foo", "foo 3"),
(vec!["foo", "foo 1", "foo 2", "foo 4"], "foo", "foo 5"),
(vec!["foo", "foo 0"], "foo", "foo 1"),
(vec!["foo 0"], "foo", "foo 1"),
] {
assert_eq!(dedup(&existing, new), expected);
}
}
}