address review: unique layer names use the numbered_name stem rule

This commit is contained in:
Dylan M. Taylor
2026-11-11 05:44:31 +00:00
parent 3be59831ac
commit a9af7224e9
3 changed files with 14 additions and 4 deletions
+1 -1
View File
@@ -271,7 +271,7 @@ impl Comp {
if !self.layers.iter().any(|l| l.name == base) {
return base.to_string();
}
let stem = base.trim_end_matches(|c: char| c.is_ascii_digit()).trim_end();
let stem = crate::item::name_stem(base);
// The suffixes in use, gathered in one pass: trying each candidate against every layer
// made importing many layers of one name cubic.
let taken: std::collections::HashSet<u64> = self
+9 -3
View File
@@ -8,12 +8,18 @@ use super::{Arc, BTreeMap, Deserialize, FrameRate, Label, Project, Serialize, Ti
/// another layer of the same name. A number set off by a space is a counter and is replaced
/// (`Red Solid 1` → `Red Solid 2`, `shot 2` → `shot 3`); digits that end a word belong to the
/// name and stay (`v-b1.mp4` → `v-b1.mp4 2`, `clip2.mov` → `clip2.mov 2`).
pub(crate) fn numbered_name(base: &str, taken: impl Fn(&str) -> bool) -> String {
/// `base` without a trailing ` N`: digits are dropped only when a space separates them from a
/// nonempty stem, so `v-b1.mp4` and `Layer1` keep theirs.
pub(crate) fn name_stem(base: &str) -> &str {
let head = base.trim_end_matches(|c: char| c.is_ascii_digit());
let stem = match head.strip_suffix(' ') {
match head.strip_suffix(' ') {
Some(stem) if head.len() < base.len() && !stem.trim_end().is_empty() => stem.trim_end(),
_ => base.trim_end(),
};
}
}
pub(crate) fn numbered_name(base: &str, taken: impl Fn(&str) -> bool) -> String {
let stem = name_stem(base);
(2u64..).map(|k| format!("{stem} {k}")).find(|n| !taken(n)).unwrap_or_default()
}
+4
View File
@@ -154,6 +154,10 @@ fn unique_names_and_cycles() {
d.layers.push(l);
}
assert_eq!(d.unique_layer_name("Red Solid 1"), "Red Solid 2");
// Digits that end a word stay in the stem.
let mut e = c.clone();
e.layers[0].name = "v-b1.mp4".into();
assert_eq!(e.unique_layer_name("v-b1.mp4"), "v-b1.mp4 2");
assert!(p.comp_contains(cid, cid));
}