diff --git a/crates/catalog/src/lib.rs b/crates/catalog/src/lib.rs index fd15415c2..10ca3617d 100644 --- a/crates/catalog/src/lib.rs +++ b/crates/catalog/src/lib.rs @@ -335,13 +335,12 @@ impl Catalog { /// rules of `from` would then change when those of `to` do). Loops in saved rules end the /// search, they don't repeat it. pub fn album_reaches(&self, from: AlbumId, to: AlbumId) -> bool { - let mut seen: Vec = Vec::new(); + let mut seen: std::collections::HashSet = std::collections::HashSet::new(); let mut next = vec![from]; while let Some(a) = next.pop() { - if seen.contains(&a) { + if !seen.insert(a) { continue; } - seen.push(a); let tested = self .albums .get(&a) diff --git a/crates/catalog/src/tests.rs b/crates/catalog/src/tests.rs index ec78153be..354d046e9 100644 --- a/crates/catalog/src/tests.rs +++ b/crates/catalog/src/tests.rs @@ -522,7 +522,8 @@ fn a_smart_album_can_exclude_another() { /// An album can't include itself, directly or through other smart albums: the check refuses the /// loop for the album being edited, and a loop saved anyway (an older version, a hand-edited file) -/// neither recurses forever nor crashes; it is reported and its rule matches nothing. +/// neither recurses forever nor crashes: inside it, the album being evaluated counts as holding no +/// photos, and every album in it is reported. #[test] fn smart_album_loops_are_refused_and_survived() { let mut c = Catalog::new();