From a4ec4672847d0815ee17a5a18bcf1d917858679a Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Tue, 19 Jan 2021 12:37:51 +1000 Subject: [PATCH] have register_tag mutate the tag if it changes it, instead of copying --- rslib/src/sync/mod.rs | 2 +- rslib/src/tags.rs | 43 +++++++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/rslib/src/sync/mod.rs b/rslib/src/sync/mod.rs index 254d34ba6..0fab5b323 100644 --- a/rslib/src/sync/mod.rs +++ b/rslib/src/sync/mod.rs @@ -898,7 +898,7 @@ impl Collection { fn merge_tags(&self, tags: Vec, latest_usn: Usn) -> Result<()> { for tag in tags { - self.register_tag(Tag::new(tag, latest_usn))?; + self.register_tag(&mut Tag::new(tag, latest_usn))?; } Ok(()) } diff --git a/rslib/src/tags.rs b/rslib/src/tags.rs index 23b460685..30fc6570c 100644 --- a/rslib/src/tags.rs +++ b/rslib/src/tags.rs @@ -204,12 +204,9 @@ impl Collection { let tags: Vec<_> = tags.iter().flat_map(|t| split_tags(t)).collect(); for tag in tags { - let t = self.register_tag(Tag::new(tag.to_string(), usn))?; - if t.0.name.is_empty() { - continue; - } - added |= t.1; - seen.insert(UniCase::new(t.0.name)); + let mut tag = Tag::new(tag.to_string(), usn); + added |= self.register_tag(&mut tag)?; + seen.insert(UniCase::new(tag.name)); } // exit early if no non-empty tags @@ -226,24 +223,26 @@ impl Collection { } /// Adjust tag casing to match any existing parents, and register it if it's not already - /// in the tags list. Returns a tuple of the tag with its name normalized, and a boolean - /// indicating if it was added. - pub(crate) fn register_tag(&self, tag: Tag) -> Result<(Tag, bool)> { + /// in the tags list. True if the tag was added and not already in tag list. + /// In the case the tag is already registered, tag will be mutated to match the existing + /// name. + pub(crate) fn register_tag(&self, tag: &mut Tag) -> Result { let normalized_name = normalize_tag_name(&tag.name); if normalized_name.is_empty() { // this should not be possible return Err(AnkiError::invalid_input("blank tag")); } - if let Some(out_tag) = self.storage.get_tag(&normalized_name)? { - // already registered - Ok((out_tag, false)) + if let Some(existing_tag) = self.storage.get_tag(&normalized_name)? { + tag.name = existing_tag.name; + Ok(false) } else { - let name = self - .adjusted_case_for_parents(&normalized_name)? - .unwrap_or_else(|| normalized_name.into()); - let out_tag = Tag { name, ..tag }; - self.storage.register_tag(&out_tag)?; - Ok((out_tag, true)) + if let Some(new_name) = self.adjusted_case_for_parents(&normalized_name)? { + tag.name = new_name; + } else if let Cow::Owned(new_name) = normalized_name { + tag.name = new_name; + } + self.storage.register_tag(&tag)?; + Ok(true) } } @@ -290,9 +289,13 @@ impl Collection { } pub(crate) fn set_tag_collapsed(&self, name: &str, collapsed: bool) -> Result<()> { + let mut name = name; + let tag; if self.storage.get_tag(name)?.is_none() { // tag is missing, register it - self.register_tag(Tag::new(name.to_string(), self.usn()?))?; + tag = Tag::new(name.to_string(), self.usn()?); + self.storage.register_tag(&tag)?; + name = &tag.name; } self.storage.set_tag_collapsed(name, collapsed) } @@ -487,7 +490,7 @@ mod test { // tag children are also cleared when clearing their parent col.storage.clear_tags()?; for name in vec!["a", "a::b", "A::b::c"] { - col.register_tag(Tag::new(name.to_string(), Usn(0)))?; + col.register_tag(&mut Tag::new(name.to_string(), Usn(0)))?; } col.storage.clear_tag("a")?; assert_eq!(col.storage.all_tags()?, vec![]);