diff --git a/crates/aaf/src/aaf/read.rs b/crates/aaf/src/aaf/read.rs index 4d20cf021..7a2ae32b6 100644 --- a/crates/aaf/src/aaf/read.rs +++ b/crates/aaf/src/aaf/read.rs @@ -330,22 +330,28 @@ impl R<'_> { } items } - x if x == cls::SELECTOR => match c.strong(pid::SELECTED) { - Some(s) => { - let mut items = self.segment(s, rate, kind, depth); - fit(&mut items, len); - items + x if x == cls::SELECTOR => { + self.report.info("a selector was flattened to its selected input"); + match c.strong(pid::SELECTED) { + Some(s) => { + let mut items = self.segment(s, rate, kind, depth); + fit(&mut items, len); + items + } + None => vec![CItem::Filler(len)], } - None => vec![CItem::Filler(len)], - }, - x if x == cls::NESTED_SCOPE => match c.objs(pid::NESTED_SLOTS).last() { - Some(s) => { - let mut items = self.segment(s, rate, kind, depth); - fit(&mut items, len); - items + } + x if x == cls::NESTED_SCOPE => { + self.report.info("a nested scope was flattened to its final input"); + match c.objs(pid::NESTED_SLOTS).last() { + Some(s) => { + let mut items = self.segment(s, rate, kind, depth); + fit(&mut items, len); + items + } + None => vec![CItem::Filler(len)], } - None => vec![CItem::Filler(len)], - }, + } _ => { self.report.info("an unsupported component was imported as a gap"); vec![CItem::Filler(len)] diff --git a/crates/aaf/src/aaf/tests.rs b/crates/aaf/src/aaf/tests.rs index 5ff6c3c7b..a0468492b 100644 --- a/crates/aaf/src/aaf/tests.rs +++ b/crates/aaf/src/aaf/tests.rs @@ -473,6 +473,35 @@ fn audio_tracks_keep_their_names() { } } +#[test] +fn flattened_selectors_and_nested_scopes_are_reported() { + for (class, property, message) in + [(cls::SELECTOR, pid::SELECTED, "selector was flattened"), (cls::NESTED_SCOPE, pid::NESTED_SLOTS, "nested scope was flattened")] + { + let mut root = store::read(&written(&document(), false)).unwrap(); + let content = strong_mut(strong_mut(&mut root, pid::ROOT_HEADER), pid::CONTENT); + let comp = objs_mut(content, pid::MOBS).iter_mut().find(|mob| mob.class == cls::COMPOSITION_MOB).unwrap(); + let slot = objs_mut(comp, pid::SLOTS) + .iter_mut() + .find(|slot| { + slot.strong(pid::SEGMENT).is_some_and(|s| s.class == cls::SEQUENCE && s.weak_key(pid::DATA_DEFINITION) == Some(&ddef::SOUND[..])) + }) + .unwrap(); + let segment = strong_mut(slot, pid::SEGMENT); + let child = segment.clone(); + let mut wrapper = Obj::new(class) + .with(pid::DATA_DEFINITION, child.get(pid::DATA_DEFINITION).unwrap().clone()) + .with(pid::LENGTH, child.get(pid::LENGTH).unwrap().clone()); + let value = if class == cls::SELECTOR { Value::Strong(Box::new(child)) } else { Value::StrongVec(vec![child]) }; + wrapper.set(property, value); + *segment = wrapper; + let bytes = store::write(&root, craft_cfb::Version::V4).unwrap(); + let mut report = Report::default(); + read(&bytes, &mut report).unwrap(); + assert!(report.mentions(message), "{report}"); + } +} + #[test] fn relative_media_locator_round_trips_escaped_characters() { let mut doc = document();