diff --git a/cli/src/main.rs b/cli/src/main.rs index 9c22789e..6842106b 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -930,8 +930,10 @@ fn chunks_for_segments( let title = format!("{} (phrase {phrase})", inputs.title); let mut meta = build_chunk_meta(&sub, path, Some(track), id, title, inputs, None); let last = end.saturating_sub(1); - meta.source.bar_range = - Some((u32::try_from(start).unwrap_or(0), u32::try_from(last).unwrap_or(0))); + meta.source.bar_range = Some(( + u32::try_from(start).unwrap_or(0), + u32::try_from(last).unwrap_or(0), + )); meta }) .collect() @@ -1580,7 +1582,11 @@ mod tests { ); // `techniques` is auto-filled from the notation… - assert!(meta.techniques.contains(&"hammer_on".to_owned()), "{:?}", meta.techniques); + assert!( + meta.techniques.contains(&"hammer_on".to_owned()), + "{:?}", + meta.techniques + ); assert!( meta.techniques.contains(&"pinch_harmonic".to_owned()), "{:?}", @@ -1588,8 +1594,16 @@ mod tests { ); // …and the curator's hand-picked tag survives alongside the derived ones. assert!(meta.tags.contains(&SwancoreTag::Intro), "{:?}", meta.tags); - assert!(meta.tags.contains(&SwancoreTag::HammerOn), "{:?}", meta.tags); - assert!(meta.tags.contains(&SwancoreTag::ArtificialHarmonic), "{:?}", meta.tags); + assert!( + meta.tags.contains(&SwancoreTag::HammerOn), + "{:?}", + meta.tags + ); + assert!( + meta.tags.contains(&SwancoreTag::ArtificialHarmonic), + "{:?}", + meta.tags + ); } #[test] @@ -1663,7 +1677,12 @@ mod tests { // Four bars, a note on each downbeat. let voice = voice_of( 0, - vec![quarter(0, 60), quarter(1920, 62), quarter(3840, 64), quarter(5760, 65)], + vec![ + quarter(0, 60), + quarter(1920, 62), + quarter(3840, 64), + quarter(5760, 65), + ], ); let score = Score { ticks_per_quarter: 480, @@ -1673,8 +1692,7 @@ mod tests { loss: LossReport::new(), }; - let chunks = - phrase_chunks(Path::new("riff.gp5"), &score, &split_inputs()).expect("splits"); + let chunks = phrase_chunks(Path::new("riff.gp5"), &score, &split_inputs()).expect("splits"); assert!(!chunks.is_empty(), "at least one phrase chunk"); // Whatever the detector decides, the chunks tile the four bars with @@ -1706,8 +1724,13 @@ mod tests { }; // A sounding [0,2) segment and a silent [2,4) one. - let chunks = - chunks_for_segments(Path::new("riff.gp5"), &score, &split_inputs(), 0, &[0..2, 2..4]); + let chunks = chunks_for_segments( + Path::new("riff.gp5"), + &score, + &split_inputs(), + 0, + &[0..2, 2..4], + ); assert_eq!(chunks.len(), 1, "the silent [2,4) segment is dropped"); assert_eq!( chunks[0].source.bar_range, @@ -1728,7 +1751,10 @@ mod tests { // track, is a rest in this phrase and must be dropped rather than // re-measured on the later track that happens to have notes there. let detected = track_of(vec![voice_of(0, vec![quarter(0, 60), quarter(1920, 62)])]); - let other = track_of(vec![voice_of(0, vec![quarter(3840, 48), quarter(5760, 50)])]); + let other = track_of(vec![voice_of( + 0, + vec![quarter(3840, 48), quarter(5760, 50)], + )]); let score = Score { ticks_per_quarter: 480, master_bars: split_master_bars(), diff --git a/core/src/dump.rs b/core/src/dump.rs index 97ebf1ee..9fc5e5a4 100644 --- a/core/src/dump.rs +++ b/core/src/dump.rs @@ -129,7 +129,10 @@ fn norm_bar(track: &Track, bar: &MasterBar) -> NormBar { .iter() .filter_map(|voice| { let notes = voice_notes_in_bar(voice, bar); - (!notes.is_empty()).then_some(NormVoice { id: voice.id, notes }) + (!notes.is_empty()).then_some(NormVoice { + id: voice.id, + notes, + }) }) .collect(); // Canonical order independent of `track.voices` import order (ADR-0020). diff --git a/core/src/novelty.rs b/core/src/novelty.rs index 07331d9f..6907d05c 100644 --- a/core/src/novelty.rs +++ b/core/src/novelty.rs @@ -236,9 +236,10 @@ pub fn flag_phrase_duplicates( #[allow(clippy::cast_precision_loss)] let share = report.longest_match_notes as f64 / report.candidate_notes as f64; match report.longest_match_reference { - Some(of) if share >= min_quote_share => { - Some(PhraseDuplicate { of, quote_share: share }) - } + Some(of) if share >= min_quote_share => Some(PhraseDuplicate { + of, + quote_share: share, + }), _ => None, } } diff --git a/core/src/split.rs b/core/src/split.rs index 78935a94..2b2d61be 100644 --- a/core/src/split.rs +++ b/core/src/split.rs @@ -146,7 +146,10 @@ mod tests { fn cuts_snap_to_their_containing_bar() { // 3840 is bar 2's downbeat; 1920 is bar 1's, 5760 is bar 3's. assert_eq!(bar_segments(&bars(4), &[3840]), vec![0..2, 2..4]); - assert_eq!(bar_segments(&bars(4), &[1920, 5760]), vec![0..1, 1..3, 3..4]); + assert_eq!( + bar_segments(&bars(4), &[1920, 5760]), + vec![0..1, 1..3, 3..4] + ); } #[test] diff --git a/core/tests/dump_golden.rs b/core/tests/dump_golden.rs index abda0476..bdd70925 100644 --- a/core/tests/dump_golden.rs +++ b/core/tests/dump_golden.rs @@ -40,7 +40,10 @@ fn sample_score() -> Score { pitch: pitch(64), velocity: Velocity::new(80).expect("valid velocity"), marks: NoteMarks::empty().with(NoteMark::Accent), - position: Some(NotePosition::explicit(FretboardPosition { string: 1, fret: 0 })), + position: Some(NotePosition::explicit(FretboardPosition { + string: 1, + fret: 0, + })), }); let plain = AtomEvent::Note(AtomNote { absolute_start: Ticks(480), diff --git a/core/tests/novelty.rs b/core/tests/novelty.rs index 2d6ab670..63df24fc 100644 --- a/core/tests/novelty.rs +++ b/core/tests/novelty.rs @@ -439,5 +439,8 @@ fn flag_phrase_duplicates_compares_the_detected_track_on_both_sides() { let flags = flag_phrase_duplicates(&phrases, 1, 0.8); let dup = flags[1].expect("the track-1 repeat is flagged despite a different track 0"); assert_eq!(dup.of, 0); - assert!(dup.quote_share >= 0.99, "the track-1 line is a verbatim repeat"); + assert!( + dup.quote_share >= 0.99, + "the track-1 line is a verbatim repeat" + ); } diff --git a/core/tests/slice_extract.rs b/core/tests/slice_extract.rs index bf5590db..90a8a3fb 100644 --- a/core/tests/slice_extract.rs +++ b/core/tests/slice_extract.rs @@ -51,7 +51,12 @@ fn bar(index: usize, start: u32) -> MasterBar { /// Four bars, one note on each downbeat (pitch 60 + bar index). fn four_bar_score() -> Score { - let notes = [note(0, 60), note(BAR, 61), note(2 * BAR, 62), note(3 * BAR, 63)]; + let notes = [ + note(0, 60), + note(BAR, 61), + note(2 * BAR, 62), + note(3 * BAR, 63), + ]; Score { ticks_per_quarter: 480, master_bars: vec![bar(0, 0), bar(1, BAR), bar(2, 2 * BAR), bar(3, 3 * BAR)], @@ -77,8 +82,7 @@ fn four_bar_score() -> Score { } fn onsets(score: &Score) -> Vec<(u32, u8)> { - score.tracks[0] - .voices[0] + score.tracks[0].voices[0] .event_groups .iter() .flat_map(|g| &g.atoms) @@ -117,5 +121,8 @@ fn empty_range_yields_no_bars_and_out_of_range_end_clamps() { // End past the last bar clamps to what exists (all four bars here). let all = extract_bars(&four_bar_score(), 0..9); assert_eq!(all.master_bars.len(), 4); - assert_eq!(onsets(&all), vec![(0, 60), (BAR, 61), (2 * BAR, 62), (3 * BAR, 63)]); + assert_eq!( + onsets(&all), + vec![(0, 60), (BAR, 61), (2 * BAR, 62), (3 * BAR, 63)] + ); } diff --git a/core/tests/technique_tags.rs b/core/tests/technique_tags.rs index 289d4ab2..34bec0a3 100644 --- a/core/tests/technique_tags.rs +++ b/core/tests/technique_tags.rs @@ -83,11 +83,26 @@ fn maps_spans_and_marks_to_direct_tags_and_a_superset_name_list() { assert!(d.tags.contains(&SwancoreTag::ArtificialHarmonic)); // Legato and accent have no dedicated SwancoreTag — they must NOT be tagged… assert!(!d.tags.contains(&SwancoreTag::NaturalHarmonic)); - assert_eq!(d.tags.len(), 3, "only the directly-taggable techniques: {:?}", d.tags); + assert_eq!( + d.tags.len(), + 3, + "only the directly-taggable techniques: {:?}", + d.tags + ); // …but the free-form name list is the superset and records them anyway. - for name in ["hammer_on", "palm_mute", "legato", "pinch_harmonic", "accent"] { - assert!(d.names.contains(&name.to_owned()), "names missing {name}: {:?}", d.names); + for name in [ + "hammer_on", + "palm_mute", + "legato", + "pinch_harmonic", + "accent", + ] { + assert!( + d.names.contains(&name.to_owned()), + "names missing {name}: {:?}", + d.names + ); } } @@ -95,7 +110,10 @@ fn maps_spans_and_marks_to_direct_tags_and_a_superset_name_list() { fn let_ring_span_derives_the_let_ring_tag_and_name() { // let-ring is newly parsed from GP (#75): a LetRing span must auto-derive // both the dedicated SwancoreTag::LetRing and the "let_ring" name. - let d = derive_techniques(&score_with(&[SpanTechnique::LetRing], NoteMarks::empty()), 0); + let d = derive_techniques( + &score_with(&[SpanTechnique::LetRing], NoteMarks::empty()), + 0, + ); assert_eq!(d.tags, vec![SwancoreTag::LetRing]); assert_eq!(d.names, vec!["let_ring".to_owned()]); } @@ -103,7 +121,10 @@ fn let_ring_span_derives_the_let_ring_tag_and_name() { #[test] fn presence_only_so_repeats_dedupe_and_output_is_deterministic() { // The same technique across groups/notes is "present", counted once. - let score = score_with(&[SpanTechnique::Slide, SpanTechnique::Slide], NoteMarks::empty()); + let score = score_with( + &[SpanTechnique::Slide, SpanTechnique::Slide], + NoteMarks::empty(), + ); let a = derive_techniques(&score, 0); let b = derive_techniques(&score, 0); assert_eq!(a, b, "pure function of the score (SPEC §6)"); @@ -125,7 +146,11 @@ fn merge_tags_keeps_chosen_order_and_appends_only_new_derived() { // HammerOn was already chosen → not duplicated; PalmMute is appended. assert_eq!( merge_tags(&chosen, &derived), - vec![SwancoreTag::Intro, SwancoreTag::HammerOn, SwancoreTag::PalmMute] + vec![ + SwancoreTag::Intro, + SwancoreTag::HammerOn, + SwancoreTag::PalmMute + ] ); // Idempotent: merging the result again changes nothing. let once = merge_tags(&chosen, &derived); @@ -158,7 +183,11 @@ fn derives_from_all_voices_like_structure_measures() { }], }); let d = derive_techniques(&score, 0); - assert!(d.tags.contains(&SwancoreTag::PalmMute), "secondary-voice span: {:?}", d.tags); + assert!( + d.tags.contains(&SwancoreTag::PalmMute), + "secondary-voice span: {:?}", + d.tags + ); assert!( d.tags.contains(&SwancoreTag::ArtificialHarmonic), "secondary-voice mark: {:?}",