1mod analyze;
26pub(crate) mod chordify;
27mod classes;
28mod consecutive;
29mod editing;
30mod ends;
31pub(crate) mod exact;
32mod filling;
33mod lookups;
34mod lyrics;
35mod opus;
36mod placed;
37mod queries;
38mod repeats;
39mod seconds;
40mod selection;
41mod slicing;
42mod sounding;
43mod span;
44mod splitting;
45mod template;
46mod ties;
47mod voices;
48
49pub use analyze::Analysis;
50pub use chordify::ChordifyOptions;
51pub use consecutive::{ConsecutiveOptions, MelodicInterval};
52pub use editing::Anchor;
53pub use lyrics::{LyricsOptions, SungAt, SungLyric, SungPlace};
54pub use placed::Placed;
55pub use queries::OffsetMapEntry;
56pub use repeats::Expander;
57pub use seconds::TempoSpan;
58pub use span::OffsetSpan;
59pub use splitting::InForce;
60pub use template::{TemplateOptions, removed_by_default};
61pub use voices::VoiceAllocation;
62
63use crate::{
64 bar::{Barline, Ending},
65 chord::Chord,
66 chordsymbol::ChordSymbol,
67 clef::Clef,
68 defaults::{FloatType, IntegerType},
69 duration::Duration,
70 dynamics::Dynamic,
71 error::Result,
72 expressions::{RehearsalMark, TextExpression},
73 instrument::Instrument,
74 interval::Interval,
75 key::{Key, KeySignature},
76 metadata::Metadata,
77 meter::TimeSignature,
78 note::Note,
79 percussion::{PercussionChord, Unpitched},
80 pitch::Pitch,
81 repeat::RepeatExpression,
82 rest::Rest,
83 spanner::{PedalObject, Spanner},
84 tempo::{MetricModulation, MetronomeMark, TempoText},
85};
86
87#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
92#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
93#[non_exhaustive]
94pub enum StreamKind {
95 #[default]
97 Stream,
98 Voice,
100 Measure,
102 Part,
104 PartStaff,
106 System,
109 Score,
111 Opus,
113}
114
115impl StreamKind {
116 pub const ALL: [StreamKind; 8] = [
118 StreamKind::Stream,
119 StreamKind::Voice,
120 StreamKind::Measure,
121 StreamKind::Part,
122 StreamKind::PartStaff,
123 StreamKind::System,
124 StreamKind::Score,
125 StreamKind::Opus,
126 ];
127
128 pub fn as_str(self) -> &'static str {
130 match self {
131 StreamKind::Stream => "Stream",
132 StreamKind::Voice => "Voice",
133 StreamKind::Measure => "Measure",
134 StreamKind::Part => "Part",
135 StreamKind::PartStaff => "PartStaff",
136 StreamKind::System => "System",
137 StreamKind::Score => "Score",
138 StreamKind::Opus => "Opus",
139 }
140 }
141}
142
143impl std::fmt::Display for StreamKind {
144 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
145 f.write_str(self.as_str())
146 }
147}
148
149#[derive(Clone, Debug)]
151#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
152#[non_exhaustive]
153pub enum StreamElement {
154 Note(Note),
156 Chord(Chord),
158 Rest(Rest),
160 Stream(Box<Stream>),
163 Clef(Clef),
165 Instrument(Box<Instrument>),
167 KeySignature(KeySignature),
169 Key(Key),
172 TimeSignature(TimeSignature),
174 MetronomeMark(MetronomeMark),
176 TempoText(TempoText),
178 TextExpression(TextExpression),
180 RepeatExpression(RepeatExpression),
182 Dynamic(Dynamic),
184 ChordSymbol(ChordSymbol),
187 Unpitched(Unpitched),
189 PercussionChord(PercussionChord),
191 Barline(Barline),
194 PedalObject(PedalObject),
197 RehearsalMark(RehearsalMark),
199 MetricModulation(Box<MetricModulation>),
202 Break(crate::volpiano::Break),
204 Layout(crate::layout::Layout),
206 TextBox(Box<crate::text::TextBox>),
208 Variant(Box<crate::variant::Variant>),
211 GlobalComment(crate::humdrum::GlobalComment),
213 MiscTandem(crate::humdrum::MiscTandem),
216 SpineComment(crate::humdrum::SpineComment),
218 BrailleSegmentDivision(crate::braille::SegmentDivision),
220}
221
222impl StreamElement {
223 pub fn duration(&self) -> Option<&Duration> {
230 match self {
231 Self::Note(note) => note.duration(),
232 Self::Chord(chord) => chord.duration(),
233 Self::Unpitched(stroke) => stroke.duration(),
234 Self::PercussionChord(chord) => chord.duration(),
235 Self::Rest(rest) => Some(rest.duration()),
236 Self::ChordSymbol(symbol) => Some(symbol.duration()),
237 Self::Stream(_)
238 | Self::Clef(_)
239 | Self::Instrument(_)
240 | Self::KeySignature(_)
241 | Self::Key(_)
242 | Self::TimeSignature(_)
243 | Self::MetronomeMark(_)
244 | Self::TempoText(_)
245 | Self::TextExpression(_)
246 | Self::RepeatExpression(_)
247 | Self::Dynamic(_)
248 | Self::Barline(_)
249 | Self::PedalObject(_)
250 | Self::RehearsalMark(_)
251 | Self::MetricModulation(_)
252 | Self::Break(_)
253 | Self::Layout(_)
254 | Self::TextBox(_)
255 | Self::Variant(_)
256 | Self::GlobalComment(_)
257 | Self::MiscTandem(_)
258 | Self::SpineComment(_)
259 | Self::BrailleSegmentDivision(_) => None,
260 }
261 }
262
263 pub fn quarter_length(&self) -> FloatType {
269 match self {
270 Self::Stream(stream) => stream.end_offset(),
271 Self::Clef(_)
272 | Self::Instrument(_)
273 | Self::KeySignature(_)
274 | Self::Key(_)
275 | Self::TimeSignature(_)
276 | Self::MetronomeMark(_)
277 | Self::TempoText(_)
278 | Self::TextExpression(_)
279 | Self::RepeatExpression(_)
280 | Self::Dynamic(_)
281 | Self::Barline(_)
282 | Self::PedalObject(_)
283 | Self::RehearsalMark(_)
284 | Self::MetricModulation(_)
285 | Self::Break(_)
286 | Self::Layout(_)
287 | Self::TextBox(_)
288 | Self::Variant(_)
289 | Self::GlobalComment(_)
290 | Self::MiscTandem(_)
291 | Self::SpineComment(_)
292 | Self::BrailleSegmentDivision(_) => 0.0,
293 _ => self
294 .duration()
295 .map(Duration::quarter_length)
296 .unwrap_or_else(|| Duration::default().quarter_length()),
297 }
298 }
299
300 pub fn pitches(&self) -> Vec<Pitch> {
303 match self {
304 Self::Note(note) => vec![note.pitch().clone()],
305 Self::Chord(chord) => chord.pitches(),
306 Self::Stream(stream) => stream.pitches(),
307 Self::PercussionChord(chord) => chord.pitches(),
308 Self::Unpitched(_)
309 | Self::Rest(_)
310 | Self::Clef(_)
311 | Self::Instrument(_)
312 | Self::KeySignature(_)
313 | Self::Key(_)
314 | Self::TimeSignature(_)
315 | Self::MetronomeMark(_)
316 | Self::TempoText(_)
317 | Self::TextExpression(_)
318 | Self::RepeatExpression(_)
319 | Self::Dynamic(_)
320 | Self::ChordSymbol(_)
321 | Self::Barline(_)
322 | Self::PedalObject(_)
323 | Self::RehearsalMark(_)
324 | Self::MetricModulation(_)
325 | Self::Break(_)
326 | Self::Layout(_)
327 | Self::TextBox(_)
328 | Self::Variant(_)
329 | Self::GlobalComment(_)
330 | Self::MiscTandem(_)
331 | Self::SpineComment(_)
332 | Self::BrailleSegmentDivision(_) => Vec::new(),
333 }
334 }
335
336 pub fn as_stream(&self) -> Option<&Stream> {
338 match self {
339 Self::Stream(stream) => Some(stream),
340 _ => None,
341 }
342 }
343
344 pub(crate) fn class_sort_order(&self) -> i32 {
347 match self {
348 Self::BrailleSegmentDivision(_) => -100,
350 Self::TextBox(_) => -31,
351 Self::TextExpression(_) | Self::RehearsalMark(_) => -30,
352 Self::Instrument(_) => -25,
353 Self::Layout(_) => -10,
354 Self::Stream(stream) if stream.kind() == StreamKind::Voice => 5,
355 Self::Stream(_) => -20,
356 Self::Variant(_) => -22,
357 Self::Barline(_) => -5,
358 Self::Clef(_) => 0,
359 Self::MetronomeMark(_) | Self::TempoText(_) | Self::MetricModulation(_) => 1,
360 Self::KeySignature(_) | Self::Key(_) => 2,
361 Self::TimeSignature(_) => 4,
362 Self::Dynamic(_) => 10,
363 Self::ChordSymbol(_) => 19,
367 Self::Chord(chord) if chord.numeral().is_some() => 19,
368 _ => 20,
369 }
370 }
371
372 pub fn is_note_or_chord(&self) -> bool {
375 matches!(self, Self::Note(_) | Self::Chord(_))
376 }
377
378 pub fn transpose(&self, interval: &Interval) -> Result<Self> {
383 match self {
384 Self::Note(note) => {
385 let mut out = note.clone();
386 out.set_pitch(interval.transpose_pitch(note.pitch())?);
387 Ok(Self::Note(out))
388 }
389 Self::Chord(chord) => Ok(Self::Chord(chord.transpose(interval)?)),
390 Self::Rest(rest) => Ok(Self::Rest(rest.clone())),
391 Self::Unpitched(stroke) => Ok(Self::Unpitched(stroke.clone())),
394 Self::PercussionChord(chord) => Ok(Self::PercussionChord(chord.clone())),
395 Self::Stream(stream) => Ok(Self::Stream(Box::new(stream.transpose(interval)?))),
396 Self::Clef(clef) => Ok(Self::Clef(clef.clone())),
397 Self::Instrument(instrument) => Ok(Self::Instrument(instrument.clone())),
398 Self::KeySignature(key) => Ok(Self::KeySignature(key.transpose(interval)?)),
399 Self::Key(key) => Ok(Self::Key(key.transpose(interval)?)),
400 Self::TimeSignature(meter) => Ok(Self::TimeSignature(meter.clone())),
401 Self::MetronomeMark(mark) => Ok(Self::MetronomeMark(mark.clone())),
402 Self::TempoText(text) => Ok(Self::TempoText(text.clone())),
403 Self::TextExpression(text) => Ok(Self::TextExpression(text.clone())),
404 Self::RepeatExpression(mark) => Ok(Self::RepeatExpression(mark.clone())),
405 Self::Dynamic(dynamic) => Ok(Self::Dynamic(dynamic.clone())),
406 Self::ChordSymbol(symbol) => Ok(Self::ChordSymbol(symbol.transpose(interval)?)),
407 Self::Barline(barline) => Ok(Self::Barline(barline.clone())),
408 Self::PedalObject(object) => Ok(Self::PedalObject(object.clone())),
409 Self::RehearsalMark(mark) => Ok(Self::RehearsalMark(mark.clone())),
410 Self::MetricModulation(modulation) => Ok(Self::MetricModulation(modulation.clone())),
411 Self::Break(kind) => Ok(Self::Break(*kind)),
412 Self::Layout(layout) => Ok(Self::Layout(layout.clone())),
413 Self::TextBox(text) => Ok(Self::TextBox(text.clone())),
414 Self::Variant(variant) => Ok(Self::Variant(Box::new(variant.transpose(interval)?))),
415 Self::GlobalComment(said) => Ok(Self::GlobalComment(said.clone())),
416 Self::MiscTandem(tandem) => Ok(Self::MiscTandem(tandem.clone())),
417 Self::SpineComment(said) => Ok(Self::SpineComment(said.clone())),
418 Self::BrailleSegmentDivision(division) => Ok(Self::BrailleSegmentDivision(*division)),
419 }
420 }
421}
422
423impl From<Barline> for StreamElement {
424 fn from(value: Barline) -> Self {
425 Self::Barline(value)
426 }
427}
428
429impl From<PedalObject> for StreamElement {
430 fn from(value: PedalObject) -> Self {
431 Self::PedalObject(value)
432 }
433}
434
435impl From<crate::humdrum::GlobalComment> for StreamElement {
436 fn from(value: crate::humdrum::GlobalComment) -> Self {
437 Self::GlobalComment(value)
438 }
439}
440
441impl From<crate::humdrum::SpineComment> for StreamElement {
442 fn from(value: crate::humdrum::SpineComment) -> Self {
443 Self::SpineComment(value)
444 }
445}
446
447impl From<crate::humdrum::MiscTandem> for StreamElement {
448 fn from(value: crate::humdrum::MiscTandem) -> Self {
449 Self::MiscTandem(value)
450 }
451}
452
453impl From<crate::braille::SegmentDivision> for StreamElement {
454 fn from(value: crate::braille::SegmentDivision) -> Self {
455 Self::BrailleSegmentDivision(value)
456 }
457}
458
459impl From<RehearsalMark> for StreamElement {
460 fn from(value: RehearsalMark) -> Self {
461 Self::RehearsalMark(value)
462 }
463}
464
465impl From<MetricModulation> for StreamElement {
466 fn from(value: MetricModulation) -> Self {
467 Self::MetricModulation(Box::new(value))
468 }
469}
470
471impl From<Note> for StreamElement {
472 fn from(value: Note) -> Self {
473 Self::Note(value)
474 }
475}
476
477impl From<Chord> for StreamElement {
478 fn from(value: Chord) -> Self {
479 Self::Chord(value)
480 }
481}
482
483impl From<Rest> for StreamElement {
484 fn from(value: Rest) -> Self {
485 Self::Rest(value)
486 }
487}
488
489impl From<Stream> for StreamElement {
490 fn from(value: Stream) -> Self {
491 Self::Stream(Box::new(value))
492 }
493}
494
495impl From<Clef> for StreamElement {
496 fn from(value: Clef) -> Self {
497 Self::Clef(value)
498 }
499}
500
501impl From<Instrument> for StreamElement {
502 fn from(value: Instrument) -> Self {
503 Self::Instrument(Box::new(value))
504 }
505}
506
507impl From<Key> for StreamElement {
508 fn from(value: Key) -> Self {
509 Self::Key(value)
510 }
511}
512
513impl From<KeySignature> for StreamElement {
514 fn from(value: KeySignature) -> Self {
515 Self::KeySignature(value)
516 }
517}
518
519impl From<TimeSignature> for StreamElement {
520 fn from(value: TimeSignature) -> Self {
521 Self::TimeSignature(value)
522 }
523}
524
525impl From<Dynamic> for StreamElement {
526 fn from(value: Dynamic) -> Self {
527 Self::Dynamic(value)
528 }
529}
530
531impl From<ChordSymbol> for StreamElement {
532 fn from(value: ChordSymbol) -> Self {
533 Self::ChordSymbol(value)
534 }
535}
536
537impl From<TextExpression> for StreamElement {
538 fn from(value: TextExpression) -> Self {
539 Self::TextExpression(value)
540 }
541}
542
543impl From<Unpitched> for StreamElement {
544 fn from(value: Unpitched) -> Self {
545 Self::Unpitched(value)
546 }
547}
548
549impl From<PercussionChord> for StreamElement {
550 fn from(value: PercussionChord) -> Self {
551 Self::PercussionChord(value)
552 }
553}
554
555impl From<RepeatExpression> for StreamElement {
556 fn from(value: RepeatExpression) -> Self {
557 Self::RepeatExpression(value)
558 }
559}
560
561impl From<TempoText> for StreamElement {
562 fn from(value: TempoText) -> Self {
563 Self::TempoText(value)
564 }
565}
566
567impl From<MetronomeMark> for StreamElement {
568 fn from(value: MetronomeMark) -> Self {
569 Self::MetronomeMark(value)
570 }
571}
572
573#[derive(Clone, Debug)]
575#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
576pub struct StreamEvent {
577 offset: FloatType,
578 element: StreamElement,
579 #[cfg_attr(feature = "serde", serde(default))]
583 priority: i32,
584}
585
586impl StreamEvent {
587 pub fn new(offset: FloatType, element: impl Into<StreamElement>) -> Self {
589 Self {
590 offset,
591 element: element.into(),
592 priority: 0,
593 }
594 }
595
596 pub fn with_priority(mut self, priority: i32) -> Self {
598 self.priority = priority;
599 self
600 }
601
602 pub fn priority(&self) -> i32 {
605 self.priority
606 }
607
608 pub fn offset(&self) -> FloatType {
610 self.offset
611 }
612
613 pub fn element_mut(&mut self) -> &mut StreamElement {
615 &mut self.element
616 }
617
618 pub fn element(&self) -> &StreamElement {
620 &self.element
621 }
622
623 pub fn end_offset(&self) -> FloatType {
625 self.offset + self.element.quarter_length()
626 }
627}
628
629#[derive(Clone, Debug, Default)]
631#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
632#[must_use]
633pub struct Stream {
634 #[cfg_attr(feature = "serde", serde(default))]
635 kind: StreamKind,
636 events: Vec<StreamEvent>,
637 #[cfg_attr(feature = "serde", serde(default))]
638 labels: Labels,
639}
640
641#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
643#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
644pub enum BarTogether {
645 Yes,
647 No,
649 Mensurstrich,
651}
652
653impl BarTogether {
654 pub fn as_str(self) -> &'static str {
656 match self {
657 Self::Yes => "yes",
658 Self::No => "no",
659 Self::Mensurstrich => "Mensurstrich",
660 }
661 }
662}
663
664#[derive(Clone, Debug, PartialEq)]
670#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
671pub struct StaffGroup {
672 parts: Vec<usize>,
673 name: Option<String>,
674 abbreviation: Option<String>,
675 symbol: Option<String>,
676 bar_together: Option<BarTogether>,
677 name_hidden: bool,
678 #[cfg_attr(feature = "serde", serde(default))]
680 pub style: crate::style::TextStyle,
681}
682
683impl StaffGroup {
684 pub fn new(parts: Vec<usize>) -> Self {
687 Self {
688 parts,
689 name: None,
690 abbreviation: None,
691 symbol: None,
692 bar_together: Some(BarTogether::Yes),
693 name_hidden: false,
694 style: crate::style::TextStyle::default(),
695 }
696 }
697
698 pub fn parts(&self) -> &[usize] {
700 &self.parts
701 }
702
703 pub fn name(&self) -> Option<&str> {
705 self.name.as_deref()
706 }
707
708 pub fn set_name(&mut self, name: Option<String>) {
710 self.name = name;
711 }
712
713 pub fn abbreviation(&self) -> Option<&str> {
715 self.abbreviation.as_deref()
716 }
717
718 pub fn set_abbreviation(&mut self, abbreviation: Option<String>) {
720 self.abbreviation = abbreviation;
721 }
722
723 pub fn symbol(&self) -> Option<&str> {
725 self.symbol.as_deref()
726 }
727
728 pub fn set_symbol(&mut self, symbol: Option<&str>) -> Result<()> {
731 self.symbol = match symbol.map(str::to_lowercase) {
732 None => None,
733 Some(symbol) if symbol == "none" => None,
734 Some(symbol) if ["brace", "line", "bracket", "square"].contains(&symbol.as_str()) => {
735 Some(symbol)
736 }
737 Some(symbol) => {
738 return Err(crate::error::Error::Value(format!(
739 "the symbol value {symbol} is not acceptable"
740 )));
741 }
742 };
743 Ok(())
744 }
745
746 pub fn bar_together(&self) -> Option<BarTogether> {
748 self.bar_together
749 }
750
751 pub fn set_bar_together(&mut self, bar_together: Option<BarTogether>) {
753 self.bar_together = bar_together;
754 }
755
756 pub fn name_hidden(&self) -> bool {
758 self.name_hidden
759 }
760
761 pub fn set_name_hidden(&mut self, hidden: bool) {
763 self.name_hidden = hidden;
764 }
765}
766
767#[derive(Clone, Debug, Default, PartialEq)]
773#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
774struct Labels {
775 number: IntegerType,
776 number_suffix: Option<String>,
777 number_hidden: bool,
778 id: Option<String>,
779 name: Option<String>,
780 abbreviation: Option<String>,
781 name_hidden: bool,
782 abbreviation_hidden: bool,
783 metadata: Option<Box<Metadata>>,
785 staff_groups: Vec<StaffGroup>,
786 left_barline: Option<Barline>,
787 right_barline: Option<Barline>,
788 spanners: Vec<Spanner>,
789 ending: Option<Ending>,
790 #[cfg_attr(feature = "serde", serde(default))]
791 padding_left: FloatType,
792 #[cfg_attr(feature = "serde", serde(default))]
793 padding_right: FloatType,
794 #[cfg_attr(feature = "serde", serde(default))]
796 layout_width: Option<crate::style::StyleValue>,
797 #[cfg_attr(feature = "serde", serde(default))]
799 at_sounding_pitch: Option<bool>,
800 #[cfg_attr(feature = "serde", serde(default))]
801 measure_numbering: Option<String>,
802}
803
804impl Stream {
805 pub fn new() -> Self {
818 Self::default()
819 }
820
821 pub fn with_kind(kind: StreamKind) -> Self {
831 Self {
832 kind,
833 ..Self::default()
834 }
835 }
836
837 pub fn number(&self) -> IntegerType {
840 self.labels.number
841 }
842
843 pub fn set_number(&mut self, number: IntegerType) {
845 self.labels.number = number;
846 }
847
848 pub fn number_suffix(&self) -> Option<&str> {
851 self.labels.number_suffix.as_deref()
852 }
853
854 pub fn set_number_suffix(&mut self, suffix: Option<String>) {
856 self.labels.number_suffix = suffix;
857 }
858
859 pub fn number_with_suffix(&self) -> String {
862 format!(
863 "{}{}",
864 self.labels.number,
865 self.labels.number_suffix.as_deref().unwrap_or("")
866 )
867 }
868
869 pub fn number_hidden(&self) -> bool {
872 self.labels.number_hidden
873 }
874
875 pub fn set_number_hidden(&mut self, hidden: bool) {
877 self.labels.number_hidden = hidden;
878 }
879
880 pub fn layout_width(&self) -> Option<&crate::style::StyleValue> {
883 self.labels.layout_width.as_ref()
884 }
885
886 pub fn set_layout_width(&mut self, width: Option<crate::style::StyleValue>) {
888 self.labels.layout_width = width;
889 }
890
891 pub fn measure_numbering(&self) -> Option<&str> {
896 self.labels.measure_numbering.as_deref()
897 }
898
899 pub fn set_measure_numbering(&mut self, numbering: Option<String>) {
901 self.labels.measure_numbering = numbering;
902 }
903
904 pub fn id(&self) -> Option<&str> {
907 self.labels.id.as_deref()
908 }
909
910 pub fn set_id(&mut self, id: Option<String>) {
912 self.labels.id = id;
913 }
914
915 pub fn name(&self) -> Option<&str> {
918 self.labels.name.as_deref()
919 }
920
921 pub fn set_name(&mut self, name: Option<String>) {
923 self.labels.name = name;
924 }
925
926 pub fn abbreviation(&self) -> Option<&str> {
929 self.labels.abbreviation.as_deref()
930 }
931
932 pub fn set_abbreviation(&mut self, abbreviation: Option<String>) {
934 self.labels.abbreviation = abbreviation;
935 }
936
937 pub fn name_hidden(&self) -> bool {
940 self.labels.name_hidden
941 }
942
943 pub fn set_name_hidden(&mut self, hidden: bool) {
945 self.labels.name_hidden = hidden;
946 }
947
948 pub fn abbreviation_hidden(&self) -> bool {
951 self.labels.abbreviation_hidden
952 }
953
954 pub fn set_abbreviation_hidden(&mut self, hidden: bool) {
956 self.labels.abbreviation_hidden = hidden;
957 }
958
959 pub fn metadata(&self) -> Option<&Metadata> {
962 self.labels.metadata.as_deref()
963 }
964
965 pub fn set_metadata(&mut self, metadata: Option<Metadata>) {
967 self.labels.metadata = metadata.map(Box::new);
968 }
969
970 pub fn staff_groups(&self) -> &[StaffGroup] {
973 &self.labels.staff_groups
974 }
975
976 pub fn add_staff_group(&mut self, group: StaffGroup) {
978 self.labels.staff_groups.push(group);
979 }
980
981 pub fn left_barline(&self) -> Option<&Barline> {
984 self.labels.left_barline.as_ref()
985 }
986
987 pub fn set_left_barline(&mut self, barline: Option<Barline>) {
989 self.labels.left_barline = barline;
990 }
991
992 pub fn right_barline(&self) -> Option<&Barline> {
995 self.labels.right_barline.as_ref()
996 }
997
998 pub fn set_right_barline(&mut self, barline: Option<Barline>) {
1000 self.labels.right_barline = barline;
1001 }
1002
1003 pub fn padding_left(&self) -> FloatType {
1006 self.labels.padding_left
1007 }
1008
1009 pub fn set_padding_left(&mut self, padding: FloatType) {
1011 self.labels.padding_left = padding;
1012 }
1013
1014 pub fn padding_right(&self) -> FloatType {
1017 self.labels.padding_right
1018 }
1019
1020 pub fn set_padding_right(&mut self, padding: FloatType) {
1022 self.labels.padding_right = padding;
1023 }
1024
1025 pub fn ending(&self) -> Option<&Ending> {
1027 self.labels.ending.as_ref()
1028 }
1029
1030 pub fn set_ending(&mut self, ending: Option<Ending>) {
1032 self.labels.ending = ending;
1033 }
1034
1035 pub fn spanners(&self) -> &[Spanner] {
1038 &self.labels.spanners
1039 }
1040
1041 pub fn add_spanner(&mut self, spanner: Spanner) {
1055 self.labels.spanners.push(spanner);
1056 }
1057
1058 pub(crate) fn clear_spanners(&mut self) {
1060 self.labels.spanners.clear();
1061 }
1062
1063 pub fn kind(&self) -> StreamKind {
1065 self.kind
1066 }
1067
1068 pub fn set_kind(&mut self, kind: StreamKind) {
1070 self.kind = kind;
1071 }
1072
1073 pub(crate) fn with_events(&self, events: Vec<StreamEvent>) -> Self {
1077 let mut labels = self.labels.clone();
1078 labels.spanners.clear();
1079 Self {
1080 kind: self.kind,
1081 events,
1082 labels,
1083 }
1084 }
1085
1086 pub fn from_events(events: impl IntoIterator<Item = StreamEvent>) -> Self {
1091 let mut stream = Self {
1092 events: events.into_iter().collect(),
1093 ..Self::default()
1094 };
1095 stream.sort_events();
1096 stream
1097 }
1098
1099 pub fn insert(&mut self, offset: FloatType, element: impl Into<StreamElement>) {
1112 self.insert_sorted(vec![StreamEvent::new(offset, element)]);
1113 }
1114
1115 pub fn push(&mut self, element: impl Into<StreamElement>) {
1128 let event = StreamEvent::new(self.end_offset(), element);
1129 let sorts_before_last = self
1132 .events
1133 .last()
1134 .is_some_and(|last| crate::makenotation::event_order(&event, last).is_lt());
1135 if sorts_before_last {
1136 self.insert_sorted(vec![event]);
1137 return;
1138 }
1139
1140 self.events.push(event);
1141 }
1142
1143 pub fn events_mut(&mut self) -> &mut [StreamEvent] {
1146 &mut self.events
1147 }
1148
1149 pub fn events(&self) -> &[StreamEvent] {
1170 &self.events
1171 }
1172
1173 pub fn iter(&self) -> impl Iterator<Item = &StreamEvent> {
1175 self.events.iter()
1176 }
1177
1178 pub fn len(&self) -> usize {
1181 self.events.len()
1182 }
1183
1184 pub fn is_empty(&self) -> bool {
1186 self.events.is_empty()
1187 }
1188
1189 pub fn first(&self) -> Option<&StreamEvent> {
1207 self.events.first()
1208 }
1209
1210 pub fn last(&self) -> Option<&StreamEvent> {
1213 self.events.last()
1214 }
1215
1216 pub fn clear(&mut self) {
1233 self.events.clear();
1234 self.labels.spanners.clear();
1235 self.labels.staff_groups.clear();
1236 self.labels.metadata = None;
1237 self.labels.left_barline = None;
1238 self.labels.right_barline = None;
1239 }
1240
1241 pub fn clef(&self) -> Option<&Clef> {
1256 self.events.iter().find_map(|event| match &event.element {
1257 StreamElement::Clef(clef) if event.offset == 0.0 => Some(clef),
1258 _ => None,
1259 })
1260 }
1261
1262 pub fn duration(&self) -> Result<Duration> {
1280 Duration::new(self.end_offset())
1281 }
1282
1283 pub fn element_by_id(&self, id: &str) -> Option<&StreamEvent> {
1302 let wanted = id.to_lowercase();
1303 self.events.iter().find(|event| {
1304 let held = match &event.element {
1305 StreamElement::Note(note) => note.id(),
1306 StreamElement::Stream(stream) => stream.id(),
1307 _ => None,
1308 };
1309 held.is_some_and(|held| held == id || held.to_lowercase() == wanted)
1310 })
1311 }
1312
1313 pub fn flatten(&self) -> Self {
1337 let mut flattened = Self::with_kind(self.kind);
1338 self.flatten_into(0.0, &mut flattened.events);
1339 flattened.events.sort_by(|left, right| {
1344 left.offset
1345 .partial_cmp(&right.offset)
1346 .unwrap_or(std::cmp::Ordering::Equal)
1347 .then_with(|| {
1348 left.element
1349 .class_sort_order()
1350 .cmp(&right.element.class_sort_order())
1351 })
1352 .then_with(|| is_grace(&right.element).cmp(&is_grace(&left.element)))
1353 });
1354 flattened
1355 }
1356
1357 fn flatten_into(&self, base: FloatType, out: &mut Vec<StreamEvent>) {
1358 for event in &self.events {
1359 let offset = crate::makenotation::op_frac(base + event.offset);
1362 match &event.element {
1363 StreamElement::Stream(stream) => stream.flatten_into(offset, out),
1364 element => out.push(StreamEvent::new(offset, element.clone())),
1365 }
1366 }
1367 }
1368
1369 pub fn recurse(&self) -> Vec<(FloatType, &StreamElement)> {
1387 let mut out = Vec::new();
1388 self.recurse_into(0.0, &mut out);
1389 out
1390 }
1391
1392 fn recurse_into<'a>(&'a self, base: FloatType, out: &mut Vec<(FloatType, &'a StreamElement)>) {
1393 for event in &self.events {
1394 let offset = crate::makenotation::op_frac(base + event.offset);
1397 out.push((offset, &event.element));
1398 if let StreamElement::Stream(stream) = &event.element {
1399 stream.recurse_into(offset, out);
1400 }
1401 }
1402 }
1403
1404 pub fn leaves(&self) -> Vec<(FloatType, &StreamElement)> {
1416 self.leaves_under_top()
1417 .into_iter()
1418 .map(|(_, offset, element)| (offset, element))
1419 .collect()
1420 }
1421
1422 pub(crate) fn leaves_under_top(&self) -> Vec<(usize, FloatType, &StreamElement)> {
1426 let mut out = Vec::new();
1427 for (top, event) in self.events.iter().enumerate() {
1428 match &event.element {
1429 StreamElement::Stream(stream) => {
1430 let mut inner = Vec::new();
1431 stream.leaves_into(event.offset, &mut inner);
1432 out.extend(
1433 inner
1434 .into_iter()
1435 .map(|(offset, element)| (top, offset, element)),
1436 );
1437 }
1438 element => out.push((top, event.offset, element)),
1439 }
1440 }
1441 out
1442 }
1443
1444 pub(crate) fn flatten_order(leaves: &[(FloatType, &StreamElement)]) -> Vec<usize> {
1454 let mut order: Vec<usize> = (0..leaves.len()).collect();
1455 order.sort_by(|left, right| {
1456 let (left_offset, left_element) = leaves[*left];
1457 let (right_offset, right_element) = leaves[*right];
1458 left_offset
1459 .total_cmp(&right_offset)
1460 .then(
1461 left_element
1462 .class_sort_order()
1463 .cmp(&right_element.class_sort_order()),
1464 )
1465 .then(is_grace(right_element).cmp(&is_grace(left_element)))
1466 });
1467 order
1468 }
1469
1470 fn leaves_into<'a>(&'a self, base: FloatType, out: &mut Vec<(FloatType, &'a StreamElement)>) {
1471 for event in &self.events {
1472 let offset = crate::makenotation::op_frac(base + event.offset);
1475 match &event.element {
1476 StreamElement::Stream(stream) => stream.leaves_into(offset, out),
1477 element => out.push((offset, element)),
1478 }
1479 }
1480 }
1481
1482 pub fn remove_event(&mut self, index: usize) -> Option<StreamEvent> {
1488 if index >= self.events.len() {
1489 return None;
1490 }
1491 let under = self.leaves_under_top();
1492 let doomed: Vec<usize> = under
1493 .iter()
1494 .enumerate()
1495 .filter(|(_, (top, _, _))| *top == index)
1496 .map(|(position, _)| position)
1497 .collect();
1498 let holds_a_stream = matches!(self.events[index].element, StreamElement::Stream(_));
1499 if holds_a_stream {
1500 self.retain_leaves(&mut |position, _| !doomed.contains(&position));
1501 return Some(self.events.remove(index));
1502 }
1503 let removed = self.events[index].clone();
1504 self.retain_leaves(&mut |position, _| !doomed.contains(&position));
1505 Some(removed)
1506 }
1507
1508 pub fn for_each_mut(&mut self, visit: &mut impl FnMut(FloatType, &mut StreamElement)) {
1517 self.for_each_mut_from(0.0, visit);
1518 }
1519
1520 fn for_each_mut_from(
1521 &mut self,
1522 base: FloatType,
1523 visit: &mut impl FnMut(FloatType, &mut StreamElement),
1524 ) {
1525 for event in &mut self.events {
1526 let offset = crate::makenotation::op_frac(base + event.offset);
1529 match &mut event.element {
1530 StreamElement::Stream(stream) => stream.for_each_mut_from(offset, visit),
1531 element => visit(offset, element),
1532 }
1533 }
1534 }
1535
1536 pub fn retain_leaves(&mut self, keep: &mut impl FnMut(usize, &mut StreamElement) -> bool) {
1541 let mut seen = 0;
1542 self.retain_leaves_from(&mut seen, keep);
1543 }
1544
1545 pub(crate) fn replace_nested(&mut self, path: &[usize], replacement: Stream) {
1550 self.edit_nested(path, |target| {
1551 let gone = vec![None; target.leaf_total()];
1552 *target = replacement;
1553 ((), gone)
1554 });
1555 }
1556
1557 pub(crate) fn edit_nested<R>(
1564 &mut self,
1565 path: &[usize],
1566 edit: impl FnOnce(&mut Stream) -> (R, Vec<Option<usize>>),
1567 ) -> (R, Vec<Option<usize>>) {
1568 let Some((&first, rest)) = path.split_first() else {
1569 return edit(self);
1570 };
1571 let total = self.leaf_total();
1572 let before: usize = self.events[..first]
1573 .iter()
1574 .map(|event| leaf_count(&event.element))
1575 .sum();
1576 let StreamElement::Stream(inner) = &mut self.events[first].element else {
1577 return edit(self);
1578 };
1579 let old = inner.leaf_total();
1580 let (answer, inner_moved) = inner.edit_nested(rest, edit);
1581 let new = inner.leaf_total();
1582 let moved: Vec<Option<usize>> = (0..total)
1583 .map(|place| {
1584 if place < before {
1585 Some(place)
1586 } else if place < before + old {
1587 inner_moved
1588 .get(place - before)
1589 .copied()
1590 .flatten()
1591 .map(|at| at + before)
1592 } else {
1593 Some(place - old + new)
1594 }
1595 })
1596 .collect();
1597 for spanner in &mut self.labels.spanners {
1598 spanner.move_places(&moved);
1599 }
1600 (answer, moved)
1601 }
1602
1603 pub(crate) fn leaf_total(&self) -> usize {
1605 self.events
1606 .iter()
1607 .map(|event| leaf_count(&event.element))
1608 .sum()
1609 }
1610
1611 pub(crate) fn replace_events(
1617 &mut self,
1618 events: Vec<(StreamEvent, Option<usize>)>,
1619 ) -> Vec<Option<usize>> {
1620 let mut starts = Vec::with_capacity(self.events.len());
1621 let mut first = 0;
1622 for event in &self.events {
1623 starts.push(first);
1624 first += leaf_count(&event.element);
1625 }
1626 let mut moved: Vec<Option<usize>> = vec![None; first];
1627 let mut placed = 0;
1628 for (event, origin) in &events {
1629 let count = leaf_count(&event.element);
1630 if let Some(&start) = origin.and_then(|origin| starts.get(origin)) {
1631 for leaf in 0..count {
1632 if let Some(slot) = moved.get_mut(start + leaf) {
1633 *slot = Some(placed + leaf);
1634 }
1635 }
1636 }
1637 placed += count;
1638 }
1639 self.events = events.into_iter().map(|(event, _)| event).collect();
1640 for spanner in &mut self.labels.spanners {
1641 spanner.move_places(&moved);
1642 }
1643 moved
1644 }
1645
1646 pub(crate) fn insert_sorted(&mut self, added: Vec<StreamEvent>) -> Vec<Option<usize>> {
1652 let mut first = 0;
1655 let mut held: Vec<(StreamEvent, Option<usize>)> = Vec::new();
1656 for event in std::mem::take(&mut self.events) {
1657 let count = leaf_count(&event.element);
1658 held.push((event, Some(first)));
1659 first += count;
1660 }
1661 held.extend(added.into_iter().map(|event| (event, None)));
1662 held.sort_by(|left, right| crate::makenotation::event_order(&left.0, &right.0));
1663 let mut moved: Vec<Option<usize>> = vec![None; first];
1664 let mut placed = 0;
1665 for (event, start) in &held {
1666 let count = leaf_count(&event.element);
1667 if let Some(start) = start {
1668 for offset in 0..count {
1669 moved[start + offset] = Some(placed + offset);
1670 }
1671 }
1672 placed += count;
1673 }
1674 self.events = held.into_iter().map(|(event, _)| event).collect();
1675 for spanner in &mut self.labels.spanners {
1676 spanner.move_places(&moved);
1677 }
1678 moved
1679 }
1680
1681 fn retain_leaves_from(
1684 &mut self,
1685 seen: &mut usize,
1686 keep: &mut impl FnMut(usize, &mut StreamElement) -> bool,
1687 ) -> Vec<Option<usize>> {
1688 let mut moved: Vec<Option<usize>> = Vec::new();
1689 let mut kept = 0;
1690 self.events.retain_mut(|event| match &mut event.element {
1691 StreamElement::Stream(inner) => {
1692 let inner_moved = inner.retain_leaves_from(seen, keep);
1693 let count = inner_moved.iter().flatten().count();
1694 moved.extend(
1695 inner_moved
1696 .into_iter()
1697 .map(|place| place.map(|place| place + kept)),
1698 );
1699 kept += count;
1700 true
1701 }
1702 element => {
1703 let position = *seen;
1704 *seen += 1;
1705 if keep(position, element) {
1706 moved.push(Some(kept));
1707 kept += 1;
1708 true
1709 } else {
1710 moved.push(None);
1711 false
1712 }
1713 }
1714 });
1715 for spanner in &mut self.labels.spanners {
1716 spanner.move_places(&moved);
1717 }
1718 moved
1719 }
1720
1721 pub fn has_part_like_streams(&self) -> bool {
1727 let mut part_like = false;
1728 for event in &self.events {
1729 let Some(stream) = event.element.as_stream() else {
1730 continue;
1731 };
1732 match stream.kind {
1733 StreamKind::Part | StreamKind::PartStaff => return true,
1734 StreamKind::Measure | StreamKind::Voice => return false,
1735 _ if event.offset != 0.0 => return false,
1736 _ => {}
1737 }
1738 let holds_music = stream.events.iter().any(|inner| {
1739 inner.element.is_instance("GeneralNote")
1740 || inner
1741 .element
1742 .as_stream()
1743 .is_some_and(|nested| nested.kind == StreamKind::Measure)
1744 });
1745 if holds_music {
1746 part_like = true;
1747 }
1748 }
1749 part_like
1750 }
1751
1752 pub fn streams_of_kind(&self, kind: StreamKind) -> Vec<&Stream> {
1755 self.events
1756 .iter()
1757 .filter_map(|event| event.element.as_stream())
1758 .filter(|stream| stream.kind == kind)
1759 .collect()
1760 }
1761
1762 pub fn parts(&self) -> Vec<&Stream> {
1765 self.events
1766 .iter()
1767 .filter_map(|event| event.element.as_stream())
1768 .filter(|stream| matches!(stream.kind, StreamKind::Part | StreamKind::PartStaff))
1769 .collect()
1770 }
1771
1772 pub fn measures(&self) -> Vec<&Stream> {
1788 self.streams_of_kind(StreamKind::Measure)
1789 }
1790
1791 pub fn voices(&self) -> Vec<&Stream> {
1793 self.streams_of_kind(StreamKind::Voice)
1794 }
1795
1796 pub fn measure(&self, number: IntegerType) -> Option<&Stream> {
1822 let measures = self.measures();
1823 if number < 0 {
1824 let index = isize::try_from(measures.len()).ok()? + isize::try_from(number).ok()?;
1825 return measures.get(usize::try_from(index).ok()?).copied();
1826 }
1827
1828 let counted = !measures.iter().any(|measure| measure.number() != 0);
1829 measures
1830 .iter()
1831 .enumerate()
1832 .find(|(index, measure)| measure_number(*index, measure, counted) == number)
1833 .map(|(_, measure)| *measure)
1834 }
1835
1836 pub fn measures_between(&self, start: IntegerType, end: Option<IntegerType>) -> Stream {
1869 if self.kind == StreamKind::Score {
1870 let mut out = self.clone_empty();
1871 out.labels.staff_groups = self.labels.staff_groups.clone();
1872 for part in self.parts() {
1873 out.events
1874 .push(StreamEvent::new(0.0, part.measures_between(start, end)));
1875 }
1876 return out;
1877 }
1878
1879 let measured: Vec<usize> = self
1880 .events
1881 .iter()
1882 .enumerate()
1883 .filter(|(_, event)| {
1884 event
1885 .element
1886 .as_stream()
1887 .is_some_and(|stream| stream.kind == StreamKind::Measure)
1888 })
1889 .map(|(index, _)| index)
1890 .collect();
1891 let counted = !measured.iter().any(|&index| {
1892 self.events[index]
1893 .element
1894 .as_stream()
1895 .is_some_and(|measure| measure.number() != 0)
1896 });
1897 let matches: Vec<usize> = measured
1898 .iter()
1899 .enumerate()
1900 .filter(|(count, index)| {
1901 let Some(measure) = self.events[**index].element.as_stream() else {
1902 return false;
1903 };
1904 let number = measure_number(*count, measure, counted);
1905 number >= start && end.is_none_or(|end| number <= end)
1906 })
1907 .map(|(_, index)| *index)
1908 .collect();
1909 let mut out = self.clone_empty();
1910 let Some(&first) = matches.first() else {
1911 return out;
1912 };
1913
1914 let begins = self.events[first].offset;
1915 let mut kept = self.collected_before(first);
1916 kept.extend(matches.iter().map(|&index| {
1917 let event = &self.events[index];
1918 let offset = crate::makenotation::op_frac(event.offset - begins);
1919 (StreamEvent::new(offset, event.element.clone()), Some(index))
1920 }));
1921 out.labels.spanners = self.labels.spanners.clone();
1922 out.events = self.events.clone();
1923 out.replace_events(kept);
1924 out.labels
1925 .spanners
1926 .retain(|spanner| spanner.spanned().iter().any(Option::is_some));
1927 out
1928 }
1929
1930 fn collected_before(&self, index: usize) -> Vec<(StreamEvent, Option<usize>)> {
1935 const COLLECTED: [&str; 5] = [
1936 "Clef",
1937 "TimeSignature",
1938 "Instrument",
1939 "KeySignature",
1940 "MetronomeMark",
1941 ];
1942 let Some(measure) = self.events[index].element.as_stream() else {
1943 return Vec::new();
1944 };
1945
1946 let begins = self.events[index].offset;
1947 let flat = self.flatten();
1948 let mut found: Vec<StreamEvent> = COLLECTED
1949 .iter()
1950 .filter(|class| !opens_with(measure, class))
1951 .filter_map(|class| {
1952 flat.events
1953 .iter()
1954 .take_while(|event| event.offset <= begins)
1955 .filter(|event| event.element.is_instance(class))
1956 .last()
1957 .map(|event| StreamEvent::new(0.0, event.element.clone()))
1958 })
1959 .collect();
1960 found.sort_by(crate::makenotation::event_order);
1962 found.into_iter().map(|event| (event, None)).collect()
1963 }
1964
1965 pub fn notes(&self) -> Vec<(FloatType, StreamElement)> {
1980 self.flatten()
1981 .events
1982 .into_iter()
1983 .filter(|event| event.element.is_note_or_chord())
1984 .map(|event| (event.offset, event.element))
1985 .collect()
1986 }
1987
1988 pub fn end_offset(&self) -> FloatType {
1992 crate::makenotation::op_frac(
1993 self.events
1994 .iter()
1995 .map(StreamEvent::end_offset)
1996 .fold(0.0, FloatType::max),
1997 )
1998 }
1999
2000 pub fn pitches(&self) -> Vec<Pitch> {
2002 self.flatten()
2003 .events
2004 .iter()
2005 .flat_map(|event| event.element.pitches())
2006 .collect()
2007 }
2008
2009 pub fn key_signature_at(&self, offset: FloatType) -> Option<KeySignature> {
2016 self.in_force_at(offset, |element| match element {
2017 StreamElement::KeySignature(key) => Some(key.clone()),
2018 StreamElement::Key(key) => Some(key.key_signature()),
2019 _ => None,
2020 })
2021 }
2022
2023 pub fn time_signature_at(&self, offset: FloatType) -> Option<TimeSignature> {
2025 self.in_force_at(offset, |element| match element {
2026 StreamElement::TimeSignature(meter) => Some(meter.clone()),
2027 _ => None,
2028 })
2029 }
2030
2031 pub fn metronome_mark_at(&self, offset: FloatType) -> Option<MetronomeMark> {
2033 self.in_force_at(offset, |element| match element {
2034 StreamElement::MetronomeMark(mark) => Some(mark.clone()),
2035 _ => None,
2036 })
2037 }
2038
2039 fn in_force_at<T>(
2041 &self,
2042 offset: FloatType,
2043 read: impl Fn(&StreamElement) -> Option<T>,
2044 ) -> Option<T> {
2045 self.flatten()
2046 .events
2047 .iter()
2048 .take_while(|event| event.offset <= offset)
2049 .filter_map(|event| read(&event.element))
2050 .last()
2051 }
2052
2053 pub fn transpose(&self, interval: &Interval) -> Result<Self> {
2055 let events = self
2056 .events
2057 .iter()
2058 .map(|event| {
2059 Ok(StreamEvent::new(
2060 event.offset,
2061 event.element.transpose(interval)?,
2062 ))
2063 })
2064 .collect::<Result<Vec<_>>>()?;
2065 let mut out = Self::with_kind(self.kind);
2066 out.labels = self.labels.clone();
2067 out.events = events;
2068 out.sort_events();
2069 Ok(out)
2070 }
2071
2072 fn sort_events(&mut self) {
2077 self.events.sort_by(|left, right| {
2078 left.offset
2079 .partial_cmp(&right.offset)
2080 .unwrap_or(std::cmp::Ordering::Equal)
2081 });
2082 }
2083}
2084
2085fn measure_number(index: usize, measure: &Stream, counted: bool) -> IntegerType {
2088 if !counted {
2089 return measure.number();
2090 }
2091
2092 IntegerType::try_from(index + 1).unwrap_or(IntegerType::MAX)
2093}
2094
2095fn opens_with(stream: &Stream, class: &str) -> bool {
2098 stream.events.iter().any(|event| {
2099 (event.offset == 0.0 && event.element.is_instance(class))
2100 || event
2101 .element
2102 .as_stream()
2103 .is_some_and(|inner| opens_with(inner, class))
2104 })
2105}
2106
2107fn is_grace(element: &StreamElement) -> bool {
2109 element.duration().is_some_and(Duration::is_grace)
2110}
2111
2112fn leaf_count(element: &StreamElement) -> usize {
2114 match element {
2115 StreamElement::Stream(inner) => inner.leaves().len(),
2116 _ => 1,
2117 }
2118}
2119
2120impl<'a> IntoIterator for &'a Stream {
2121 type Item = &'a StreamEvent;
2122 type IntoIter = std::slice::Iter<'a, StreamEvent>;
2123
2124 fn into_iter(self) -> Self::IntoIter {
2125 self.events.iter()
2126 }
2127}
2128
2129#[cfg(test)]
2130mod tests {
2131 #[test]
2132 fn a_stream_has_part_like_streams_as_music21_decides() {
2133 use super::{Stream, StreamKind};
2134 use crate::note::Note;
2135
2136 let four_notes = |kind: StreamKind| {
2139 let mut stream = Stream::with_kind(kind);
2140 for _ in 0..4 {
2141 stream.push(Note::from_name("C4").unwrap());
2142 }
2143 stream
2144 };
2145 let mut score = Stream::with_kind(StreamKind::Score);
2146 assert!(!score.has_part_like_streams());
2147 score.insert(0.0, four_notes(StreamKind::Part));
2148 assert!(score.has_part_like_streams());
2149
2150 let mut score = Stream::with_kind(StreamKind::Score);
2151 score.push(four_notes(StreamKind::Measure));
2152 assert!(!score.has_part_like_streams());
2153
2154 let mut score = Stream::with_kind(StreamKind::Score);
2155 score.push(four_notes(StreamKind::Stream));
2156 assert!(score.has_part_like_streams());
2157 score.push(four_notes(StreamKind::Stream));
2158 assert!(!score.has_part_like_streams());
2159 }
2160
2161 #[test]
2162 fn a_stream_says_what_kind_it_is_and_walks_its_events() {
2163 use super::{Stream, StreamElement, StreamEvent, StreamKind};
2164 use crate::note::Note;
2165 use crate::pitch::Pitch;
2166 use crate::tempo::MetronomeMark;
2167
2168 assert_eq!(StreamKind::Voice.as_str(), "Voice");
2169 assert_eq!(StreamKind::Voice.to_string(), "Voice");
2170 let mut stream = Stream::new();
2171 assert!(stream.is_empty());
2172 stream.set_kind(StreamKind::Voice);
2173 assert_eq!(stream.kind(), StreamKind::Voice);
2174 assert!(matches!(
2175 StreamElement::from(MetronomeMark::new(120.0)),
2176 StreamElement::MetronomeMark(_)
2177 ));
2178
2179 let note = Note::from_pitch(Pitch::from_name("C4").unwrap());
2180 let rebuilt = Stream::from_events([StreamEvent::new(0.0, note)]);
2181 assert_eq!(rebuilt.iter().count(), 1);
2182 assert!(!rebuilt.is_empty());
2183 assert!(rebuilt.voices().is_empty());
2184 let mut outer = Stream::new();
2185 outer.push(stream);
2186 assert_eq!(outer.voices().len(), 1);
2187 }
2188
2189 use super::*;
2190
2191 #[test]
2192 fn a_stream_iterates_by_reference() {
2193 let mut stream = Stream::new();
2194 stream.push(Note::from_name("C4").unwrap());
2195 stream.push(Note::from_name("E4").unwrap());
2196
2197 let offsets: Vec<FloatType> = (&stream).into_iter().map(StreamEvent::offset).collect();
2198 assert_eq!(offsets, vec![0.0, 1.0]);
2199 assert_eq!((&stream).into_iter().count(), stream.len());
2200 }
2201
2202 #[test]
2203 fn stream_push_uses_durations() {
2204 let mut stream = Stream::new();
2205 stream.push(
2206 Note::from_name("C4")
2207 .unwrap()
2208 .with_duration(Duration::half()),
2209 );
2210 stream.push(Rest::from_quarter_length(0.5).unwrap());
2211 assert_eq!(stream.events()[0].offset(), 0.0);
2212 assert_eq!(stream.events()[1].offset(), 2.0);
2213 assert_eq!(stream.end_offset(), 2.5);
2214 }
2215
2216 #[test]
2217 fn a_clef_inserted_after_a_note_sorts_before_it() {
2218 let mut stream = Stream::new();
2221 stream.insert(0.0, Note::from_name("C4").unwrap());
2222 stream.insert(0.0, Clef::treble());
2223 assert!(matches!(
2224 stream.events()[0].element(),
2225 StreamElement::Clef(_)
2226 ));
2227 assert!(matches!(
2228 stream.events()[1].element(),
2229 StreamElement::Note(_)
2230 ));
2231 }
2232
2233 #[test]
2234 fn a_clef_pushed_after_a_dynamic_sorts_before_it() {
2235 let mut stream = Stream::new();
2238 stream.push(Dynamic::new("p"));
2239 stream.push(Clef::treble());
2240 assert!(matches!(
2241 stream.events()[0].element(),
2242 StreamElement::Clef(_)
2243 ));
2244 assert!(matches!(
2245 stream.events()[1].element(),
2246 StreamElement::Dynamic(_)
2247 ));
2248 }
2249
2250 #[test]
2251 fn first_and_last_follow_the_streams_order() {
2252 let mut stream = Stream::new();
2253 assert!(stream.first().is_none());
2254 assert!(stream.last().is_none());
2255 stream.insert(1.0, Note::from_name("D4").unwrap());
2256 stream.insert(0.0, Note::from_name("C4").unwrap());
2257 stream.insert(0.0, Clef::treble());
2258 assert!(matches!(
2259 stream.first().unwrap().element(),
2260 StreamElement::Clef(_)
2261 ));
2262 assert_eq!(stream.last().unwrap().offset(), 1.0);
2263 }
2264
2265 #[test]
2266 fn clear_takes_out_what_music21_holds_as_elements() {
2267 let mut measure = Stream::with_kind(StreamKind::Measure);
2268 measure.set_number(3);
2269 measure.set_id(Some("m3".to_string()));
2270 measure.push(Note::from_name("C4").unwrap());
2271 measure.set_right_barline(Some(Barline::default()));
2272 measure.set_left_barline(Some(Barline::default()));
2273 measure.set_metadata(Some(Metadata::default()));
2274 measure.add_staff_group(StaffGroup::new(vec![0]));
2275 measure.clear();
2276 assert!(measure.is_empty());
2277 assert!(measure.right_barline().is_none());
2278 assert!(measure.left_barline().is_none());
2279 assert!(measure.metadata().is_none());
2280 assert!(measure.staff_groups().is_empty());
2281 assert!(measure.spanners().is_empty());
2282 assert_eq!(measure.number(), 3);
2283 assert_eq!(measure.id(), Some("m3"));
2284 assert_eq!(measure.kind(), StreamKind::Measure);
2285 }
2286
2287 #[test]
2288 fn the_clef_is_one_held_at_the_start() {
2289 let mut measure = Stream::with_kind(StreamKind::Measure);
2290 measure.insert(2.0, Clef::bass());
2291 assert!(
2292 measure.clef().is_none(),
2293 "a clef later on is not the opening one"
2294 );
2295 measure.insert(0.0, Clef::treble());
2296 assert_eq!(measure.clef().unwrap().sign(), Some("G"));
2297
2298 let mut part = Stream::with_kind(StreamKind::Part);
2299 part.push(measure);
2300 assert!(part.clef().is_none(), "a measure's clef is not its part's");
2301 }
2302
2303 #[test]
2304 fn a_streams_duration_is_its_highest_time() {
2305 let mut stream = Stream::new();
2306 assert_eq!(stream.duration().unwrap().quarter_length(), 0.0);
2307 stream.repeat_insert(
2308 &Note::from_name("C4").unwrap().into(),
2309 &[0.0, 1.0, 2.0, 3.0],
2310 );
2311 assert_eq!(stream.duration().unwrap().quarter_length(), 4.0);
2312 stream.insert(FloatType::INFINITY, Clef::treble());
2313 assert!(stream.duration().is_err());
2314 }
2315
2316 #[test]
2317 fn an_element_is_found_by_its_id_in_any_case() {
2318 let mut note = Note::from_name("C4").unwrap();
2319 note.set_id(Some("green".to_string()));
2320 let mut stream = Stream::new();
2321 stream.push(Rest::default());
2322 stream.push(note);
2323 assert_eq!(stream.element_by_id("Green").unwrap().offset(), 1.0);
2324 assert!(stream.element_by_id("blue").is_none());
2325
2326 let mut outer = Stream::new();
2328 outer.push(stream);
2329 assert!(outer.element_by_id("green").is_none());
2330 }
2331
2332 fn numbered_part(numbers: &[IntegerType]) -> Stream {
2335 let mut part = Stream::with_kind(StreamKind::Part);
2336 for (index, &number) in numbers.iter().enumerate() {
2337 let mut measure = Stream::with_kind(StreamKind::Measure);
2338 measure.set_number(number);
2339 if index == 0 {
2340 measure.insert(0.0, Clef::bass());
2341 measure.insert(0.0, TimeSignature::new(4, 4).unwrap());
2342 measure.insert(0.0, KeySignature::new(1));
2343 }
2344 if index == 2 {
2345 measure.insert(0.0, KeySignature::new(-2));
2346 }
2347 measure.push(
2348 Note::from_name("C3")
2349 .unwrap()
2350 .with_duration(Duration::whole()),
2351 );
2352 part.push(measure);
2353 }
2354 part
2355 }
2356
2357 #[test]
2358 fn a_measure_is_found_by_its_number() {
2359 let part = numbered_part(&[0, 1, 2, 3]);
2360 assert_eq!(part.measure(0).unwrap().number(), 0);
2361 assert_eq!(part.measure(2).unwrap().number(), 2);
2362 assert!(part.measure(9).is_none());
2363 assert_eq!(part.measure(-1).unwrap().number(), 3);
2364 assert_eq!(part.measure(-4).unwrap().number(), 0);
2365 assert!(part.measure(-5).is_none());
2366
2367 let unnumbered = numbered_part(&[0, 0, 0]);
2369 assert!(unnumbered.measure(0).is_none());
2370 assert_eq!(unnumbered.measure(2).unwrap().end_offset(), 4.0);
2371 assert!(std::ptr::eq(
2372 unnumbered.measure(2).unwrap(),
2373 unnumbered.measures()[1]
2374 ));
2375 }
2376
2377 #[test]
2378 fn measures_between_collect_what_is_in_force() {
2379 let part = numbered_part(&[1, 2, 3, 4]);
2380 let excerpt = part.measures_between(2, Some(3));
2381 assert_eq!(excerpt.kind(), StreamKind::Part);
2382 let classes: Vec<&str> = excerpt
2383 .events()
2384 .iter()
2385 .map(|event| event.element().music21_classes()[0])
2386 .collect();
2387 assert_eq!(
2388 classes,
2389 [
2390 "BassClef",
2391 "KeySignature",
2392 "TimeSignature",
2393 "Measure",
2394 "Measure"
2395 ]
2396 );
2397 assert!(
2398 excerpt
2399 .events()
2400 .iter()
2401 .take(3)
2402 .all(|event| event.offset() == 0.0)
2403 );
2404 let numbers: Vec<IntegerType> = excerpt.measures().iter().map(|m| m.number()).collect();
2405 assert_eq!(numbers, [2, 3]);
2406 assert_eq!(excerpt.events()[4].offset(), 4.0);
2407
2408 let from_three = part.measures_between(3, None);
2410 let keys = from_three
2411 .events()
2412 .iter()
2413 .filter(|event| event.element().is_instance("KeySignature"))
2414 .count();
2415 assert_eq!(keys, 0);
2416 assert_eq!(from_three.measures().len(), 2);
2417
2418 assert_eq!(part.measures_between(1, Some(1)).len(), 1);
2420 assert!(part.measures_between(7, Some(9)).is_empty());
2421 }
2422
2423 #[test]
2424 fn a_score_answers_measures_of_each_part() {
2425 let mut score = Stream::with_kind(StreamKind::Score);
2426 score.set_id(Some("full".to_string()));
2427 score.insert(0.0, numbered_part(&[1, 2, 3]));
2428 score.insert(0.0, numbered_part(&[1, 2, 3]));
2429 score.add_staff_group(StaffGroup::new(vec![0, 1]));
2430 let slice = score.measures_between(2, Some(2));
2431 assert_eq!(slice.kind(), StreamKind::Score);
2432 assert_eq!(slice.id(), Some("full"));
2433 assert_eq!(slice.parts().len(), 2);
2434 assert_eq!(slice.parts()[1].measures().len(), 1);
2435 assert_eq!(slice.staff_groups().len(), 1);
2436 }
2437
2438 #[test]
2439 fn stream_transposes_notes_and_chords() {
2440 let mut stream = Stream::new();
2441 stream.push(Note::from_name("C4").unwrap());
2442 stream.push(Chord::new("E4 G4").unwrap());
2443 let out = stream
2444 .transpose(&Interval::from_name("M2").unwrap())
2445 .unwrap();
2446 let names = out
2447 .pitches()
2448 .iter()
2449 .map(Pitch::name_with_octave)
2450 .collect::<Vec<_>>();
2451 assert_eq!(names, vec!["D4", "F#4", "A4"]);
2452 }
2453
2454 fn two_measure_score() -> Stream {
2457 let mut first = Stream::with_kind(StreamKind::Measure);
2458 first.insert(0.0, KeySignature::new(2));
2459 first.insert(0.0, TimeSignature::new(4, 4).unwrap());
2460 first.push(Note::from_name("D4").unwrap());
2461 first.push(Note::from_name("E4").unwrap());
2462 first.push(Note::from_name("F#4").unwrap());
2463 first.push(Note::from_name("G4").unwrap());
2464
2465 let mut second = Stream::with_kind(StreamKind::Measure);
2466 second.insert(0.0, KeySignature::new(-1));
2467 second.push(Note::from_name("A4").unwrap());
2468 second.push(Note::from_name("Bb4").unwrap());
2469
2470 let mut part = Stream::with_kind(StreamKind::Part);
2471 part.push(first);
2472 part.push(second);
2473
2474 let mut score = Stream::with_kind(StreamKind::Score);
2475 score.push(part);
2476 score
2477 }
2478
2479 #[test]
2480 fn a_nested_stream_flattens_onto_one_timeline() {
2481 let score = two_measure_score();
2482 assert_eq!(score.kind(), StreamKind::Score);
2483 assert_eq!(score.len(), 1, "a score holds its one part, not its notes");
2484 assert_eq!(score.parts().len(), 1);
2485 assert_eq!(score.parts()[0].measures().len(), 2);
2486
2487 let notes = score.notes();
2489 let offsets: Vec<FloatType> = notes.iter().map(|(offset, _)| *offset).collect();
2490 assert_eq!(offsets, vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
2491 assert_eq!(score.end_offset(), 6.0);
2492
2493 let names: Vec<String> = score
2494 .pitches()
2495 .iter()
2496 .map(Pitch::name_with_octave)
2497 .collect();
2498 assert_eq!(names, ["D4", "E4", "F#4", "G4", "A4", "Bb4"]);
2499
2500 assert_eq!(score.recurse().len(), 1 + 2 + 6 + 3);
2502 assert_eq!(score.flatten().len(), 6 + 3);
2503 }
2504
2505 #[test]
2506 fn the_key_in_force_is_the_last_one_written_before_it() {
2507 let score = two_measure_score();
2508 assert_eq!(score.key_signature_at(0.0).unwrap().sharps(), 2);
2509 assert_eq!(score.key_signature_at(3.5).unwrap().sharps(), 2);
2510 assert_eq!(score.key_signature_at(4.0).unwrap().sharps(), -1);
2512 assert_eq!(score.key_signature_at(100.0).unwrap().sharps(), -1);
2513 assert_eq!(
2514 score.time_signature_at(5.0).unwrap().ratio_string(),
2515 "4/4",
2516 "a metre stays in force across the bar that follows it"
2517 );
2518 assert!(score.metronome_mark_at(0.0).is_none());
2519
2520 let mut late = Stream::new();
2522 late.insert(2.0, KeySignature::new(3));
2523 assert!(late.key_signature_at(1.0).is_none());
2524 assert_eq!(late.key_signature_at(2.0).unwrap().sharps(), 3);
2525 }
2526
2527 #[test]
2528 fn transposing_a_score_moves_its_key_signatures_too() {
2529 let score = two_measure_score();
2530 let up = score
2531 .transpose(&Interval::from_name("M2").unwrap())
2532 .unwrap();
2533 assert_eq!(up.key_signature_at(0.0).unwrap().sharps(), 4);
2534 assert_eq!(up.key_signature_at(4.0).unwrap().sharps(), 1);
2535 let names: Vec<String> = up.pitches().iter().map(Pitch::name_with_octave).collect();
2536 assert_eq!(names, ["E4", "F#4", "G#4", "A4", "B4", "C5"]);
2537 assert_eq!(up.kind(), StreamKind::Score);
2538 }
2539}