LRC-LIB-LIBFOLDERS: a folder located below itself leaves the records already at its destination in place

This commit is contained in:
Nathaniel Ledford
2026-10-22 15:32:44 -04:00
parent a9be2e14f3
commit 5d24e34ed5
2 changed files with 26 additions and 2 deletions
+7 -2
View File
@@ -223,10 +223,15 @@ impl Catalog {
if root == dest {
return Vec::new();
}
// a folder located below itself: what is already at or below `to` belongs to the folders
// of the library there, not to the folder located, so it is neither carried nor cleared
// (the record of `from` itself still lands at `to`, replacing the one there)
let nested = !clear_destination && key_within(&dest, &root);
let carried = |k: &str| key_within(k, &root) && !(nested && key_within(k, &dest));
let moved: Vec<(String, FolderRecord)> = self
.folder_records
.iter()
.filter(|(k, _)| key_within(k, &root))
.filter(|(k, _)| carried(k))
.filter_map(|(k, r)| {
let rest = folder_rest(k, &root)?;
let base = dest.trim_end_matches('/');
@@ -236,7 +241,7 @@ impl Catalog {
.collect();
// what was known at the old place goes, and so does what is left at the new one (also
// when the moved folder carries nothing: the folder now there is not the one it was about)
let stale = self.folder_records.keys().filter(|k| key_within(k, &root) || (clear_destination && key_within(k, &dest)));
let stale = self.folder_records.keys().filter(|k| carried(k) || (clear_destination && key_within(k, &dest)));
let mut ops: Vec<Op> = stale.map(|k| Op::SetFolderRecord { folder: k.clone(), record: None }).collect();
ops.extend(moved.into_iter().map(|(k, r)| Op::SetFolderRecord { folder: k, record: Some(r) }));
ops
@@ -191,6 +191,25 @@ fn a_located_folder_with_labels_inside_lands_them_at_the_same_places_below() {
assert_eq!(c.folder_color_label("/mnt/nas/trip/day1"), Some(ColorLabel::Green));
}
#[test]
fn a_folder_located_below_itself_leaves_the_records_of_the_folders_already_there_in_place() {
let mut c = library();
label(&mut c, "/pics/trip", Some(ColorLabel::Red));
label(&mut c, "/pics/trip/day1", Some(ColorLabel::Green));
// another folder of the library already sits at the place the folder is said to be at
label(&mut c, "/pics/trip/day1/raw", Some(ColorLabel::Blue));
let before = c.to_snapshot();
let ops = c.folder_records_located("/pics/trip", "/pics/trip/day1");
let undo = c.apply(Op::Batch { ops }).unwrap();
assert_eq!(c.folder_record("/pics/trip"), None, "what was known at the old place goes");
assert_eq!(c.folder_color_label("/pics/trip/day1"), Some(ColorLabel::Red), "a record carried over replaces the one at the same place");
assert_eq!(c.folder_color_label("/pics/trip/day1/raw"), Some(ColorLabel::Blue), "a folder below the destination keeps its own");
assert_eq!(c.folder_record("/pics/trip/day1/day1"), None, "the record at the destination is not carried below itself");
assert_eq!(c.folder_record("/pics/trip/day1/day1/raw"), None);
c.apply(undo).unwrap();
assert_eq!(c.to_snapshot(), before);
}
#[test]
fn a_folder_located_where_it_is_or_without_labels_gives_no_ops() {
let mut c = library();