Skip to content

Commit 9bd6905

Browse files
committed
Remove tags when last entry is removed
1 parent 316543e commit 9bd6905

File tree

1 file changed

+37
-5
lines changed

1 file changed

+37
-5
lines changed

src/registry.rs

+37-5
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,28 @@ impl TagRegistry {
105105
None
106106
}
107107

108+
fn clean_tag_if_no_entries(&mut self, tag: &Tag) {
109+
let remove = if let Some(entries) = self.tags.get(tag) {
110+
entries.is_empty()
111+
} else {
112+
false
113+
};
114+
115+
if remove {
116+
self.tags.remove(tag);
117+
}
118+
}
119+
108120
/// Removes the `tag` from an entry with `entry` id. Returns the entry data if it has no tags
109121
/// left or `None` otherwise.
110122
pub fn untag_entry(&mut self, tag: &Tag, entry: EntryId) -> Option<EntryData> {
111123
let entries = self.mut_tag_entries(tag);
112124

113125
if let Some(pos) = entries.iter().position(|e| *e == entry) {
114126
let entry = entries.remove(pos);
127+
128+
self.clean_tag_if_no_entries(tag);
129+
115130
if self.list_entry_tags(entry).is_none() {
116131
return self.entries.remove(&entry);
117132
}
@@ -129,11 +144,20 @@ impl TagRegistry {
129144

130145
/// Clears all tags of the `entry`.
131146
pub fn clear_entry(&mut self, entry: EntryId) {
132-
self.tags.iter_mut().for_each(|(_, entries)| {
147+
let mut to_remove = vec![];
148+
self.tags.iter_mut().for_each(|(tag, entries)| {
133149
if let Some(idx) = entries.iter().copied().position(|e| e == entry) {
134150
entries.remove(idx);
135151
}
152+
if entries.is_empty() {
153+
to_remove.push(tag.to_owned());
154+
}
136155
});
156+
157+
for tag in to_remove {
158+
self.tags.remove(&tag);
159+
}
160+
137161
self.entries.remove(&entry);
138162
}
139163

@@ -300,26 +324,34 @@ mod tests {
300324
let mut registry = TagRegistry::default();
301325
let id = registry.add_or_update_entry(entry.clone());
302326

303-
let tag = Tag::new("test", Black);
327+
let tag1 = Tag::new("test", Black);
304328
let tag2 = Tag::new("test2", Red);
305329

306-
assert!(registry.tag_entry(&tag, id).is_none());
330+
assert!(registry.tag_entry(&tag1, id).is_none());
331+
assert_eq!(registry.tags.iter().next(), Some((&tag1, &vec![id])));
307332
assert_eq!(registry.list_entries().count(), 1);
308-
assert_eq!(registry.untag_entry(&tag, id), Some(entry.clone()));
333+
assert_eq!(registry.untag_entry(&tag1, id), Some(entry.clone()));
309334
assert_eq!(registry.list_entries().count(), 0);
335+
assert!(registry.tags.is_empty());
310336

311337
let id = registry.add_or_update_entry(entry.clone());
312338
assert!(registry.tag_entry(&tag2, id).is_none());
339+
assert_eq!(registry.tags.iter().next(), Some((&tag2, &vec![id])));
313340
assert_eq!(registry.list_entries().count(), 1);
314341
assert_eq!(registry.untag_by_name(tag2.name(), id), Some(entry.clone()));
315342
assert_eq!(registry.list_entries().count(), 0);
343+
assert!(registry.tags.is_empty());
316344

317345
let id = registry.add_or_update_entry(entry);
318-
assert!(registry.tag_entry(&tag, id).is_none());
346+
assert!(registry.tag_entry(&tag1, id).is_none());
319347
assert!(registry.tag_entry(&tag2, id).is_none());
348+
let tags: Vec<_> = registry.tags.iter().collect();
349+
assert!(tags.contains(&(&tag1, &vec![id])));
350+
assert!(tags.contains(&(&tag2, &vec![id])));
320351
assert_eq!(registry.list_entries().count(), 1);
321352
registry.clear_entry(id);
322353
assert_eq!(registry.list_entries().count(), 0);
354+
assert!(registry.tags.is_empty());
323355
}
324356

325357
#[test]

0 commit comments

Comments
 (0)