diff --git a/crates/catalog/src/local.rs b/crates/catalog/src/local.rs index 093c22427..184618ac9 100644 --- a/crates/catalog/src/local.rs +++ b/crates/catalog/src/local.rs @@ -64,7 +64,8 @@ pub fn folder_of(p: &Photo) -> Option { // `/` and `\` are both separators whatever the platform (a catalog can move between them) Source::File { path } => { let key = crate::query::folder_key(path); - key.rsplit_once('/').map(|(dir, _)| if dir.is_empty() { "/".to_string() } else { dir.to_string() }) + // a drive or share root keeps its trailing `/` in its key (`c:/`, `//srv/share/`) + key.rsplit_once('/').map(|(dir, _)| if dir.is_empty() { "/".to_string() } else { crate::query::folder_key(&format!("{dir}/")) }) } Source::Demo { .. } => None, } diff --git a/crates/catalog/src/tests_local.rs b/crates/catalog/src/tests_local.rs index 4b76dace6..ca6ebef0d 100644 --- a/crates/catalog/src/tests_local.rs +++ b/crates/catalog/src/tests_local.rs @@ -265,3 +265,17 @@ fn op_photo_ids_cover_nested_ops() { op.photo_ids(&mut |id| ids.push(id.0)); assert_eq!(ids, vec![1, 2, 3, 4]); } + +#[test] +fn drive_and_share_root_records_are_forgotten() { + for (path, folder) in [("C:\\IMG_1.JPG", "C:\\"), ("//srv/share/x.jpg", "//srv/share/")] { + let mut c = Catalog::new(); + let id = c.alloc_photo_id(); + let mut p = Photo::new(id, Source::File { path: path.into() }, "x.jpg", "JPEG", 60, 40, OLD); + p.local = true; + p.set_local_baseline(); + c.apply(Op::AddPhoto { photo: Box::new(p) }).unwrap(); + c.apply(Op::SetBrowsed { folder: folder.into(), at: Some(OLD.into()) }).unwrap(); + assert_eq!(plan(&c, 30).evict, vec![id], "{path}"); + } +}