Skip to main content

music21_rs/
stream.rs

1//! Music on a timeline: music21's `stream.Stream` and the subclasses it
2//! nests inside one another.
3//!
4//! A [`Stream`] is a list of things at quarter-length offsets, and one of
5//! those things may be another stream: a score holds parts, a part holds
6//! measures, a measure holds voices and notes. [`Stream::flatten`] dissolves
7//! that nesting into one timeline the way music21's does, adding each
8//! stream's own offset to its contents'.
9//!
10//! **What is deliberately not here is music21's *sites*.** There an object
11//! can sit in several streams at once and carry a different offset in each,
12//! which is why it needs a back-reference to every stream holding it and why
13//! `getContextByClass` has a graph to walk. A stream here *owns* what it
14//! holds, so the nesting is a tree; asking what key or metre is in force at
15//! an offset is then a backwards look through the flattened timeline rather
16//! than a search through a graph. That is the same answer for music that is
17//! written once, which is all a stream built here can be.
18//!
19//! Where an element sits is asked for, not stored: [`Stream::placed`]
20//! answers each element with its offset, its measure offset and the key,
21//! metre and tempo in force, as one [`Placed`](crate::stream::Placed) value. music21's author
22//! names keeping objects and sites apart this way as what he would do
23//! again.
24
25mod 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 seconds::TempoSpan;
57pub use span::OffsetSpan;
58pub use splitting::InForce;
59pub use template::{TemplateOptions, removed_by_default};
60pub use voices::VoiceAllocation;
61
62use crate::{
63    bar::{Barline, Ending},
64    chord::Chord,
65    chordsymbol::ChordSymbol,
66    clef::Clef,
67    defaults::{FloatType, IntegerType},
68    duration::Duration,
69    dynamics::Dynamic,
70    error::Result,
71    expressions::{RehearsalMark, TextExpression},
72    instrument::Instrument,
73    interval::Interval,
74    key::{Key, KeySignature},
75    metadata::Metadata,
76    meter::TimeSignature,
77    note::Note,
78    percussion::{PercussionChord, Unpitched},
79    pitch::Pitch,
80    repeat::RepeatExpression,
81    rest::Rest,
82    spanner::{PedalObject, Spanner},
83    tempo::{MetricModulation, MetronomeMark, TempoText},
84};
85
86/// Which of music21's `Stream` subclasses a stream stands for.
87///
88/// music21 makes each of these a class of its own; they carry no behaviour
89/// that a tag does not, and a tag is what the filters here need.
90#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
91#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
92pub enum StreamKind {
93    /// A stream with no particular role: music21's `Stream`.
94    #[default]
95    Stream,
96    /// One independent line inside a measure.
97    Voice,
98    /// One bar.
99    Measure,
100    /// One instrument's line through the piece.
101    Part,
102    /// One staff of a part written on several.
103    PartStaff,
104    /// A whole piece, holding parts.
105    Score,
106    /// A collection of scores.
107    Opus,
108}
109
110impl StreamKind {
111    /// Every kind, in music21's order of containment.
112    pub const ALL: [StreamKind; 7] = [
113        StreamKind::Stream,
114        StreamKind::Voice,
115        StreamKind::Measure,
116        StreamKind::Part,
117        StreamKind::PartStaff,
118        StreamKind::Score,
119        StreamKind::Opus,
120    ];
121
122    /// music21's class name for this kind.
123    pub fn as_str(self) -> &'static str {
124        match self {
125            StreamKind::Stream => "Stream",
126            StreamKind::Voice => "Voice",
127            StreamKind::Measure => "Measure",
128            StreamKind::Part => "Part",
129            StreamKind::PartStaff => "PartStaff",
130            StreamKind::Score => "Score",
131            StreamKind::Opus => "Opus",
132        }
133    }
134}
135
136impl std::fmt::Display for StreamKind {
137    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
138        f.write_str(self.as_str())
139    }
140}
141
142/// A musical object that can live on a timeline.
143#[derive(Clone, Debug)]
144#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
145pub enum StreamElement {
146    /// A single pitched note.
147    Note(Note),
148    /// A chord containing one or more notes.
149    Chord(Chord),
150    /// A silent rest.
151    Rest(Rest),
152    /// A stream nested inside this one: a part in a score, a measure in a
153    /// part. Boxed, since a stream holds these by value.
154    Stream(Box<Stream>),
155    /// The clef in force from here on.
156    Clef(Clef),
157    /// The instrument playing from here on. Boxed: an instrument is large.
158    Instrument(Box<Instrument>),
159    /// The key signature in force from here on.
160    KeySignature(KeySignature),
161    /// The key in force from here on: a key signature that also says its
162    /// tonic and mode, as music21's `Key` is a `KeySignature`.
163    Key(Key),
164    /// The metre in force from here on.
165    TimeSignature(TimeSignature),
166    /// The tempo in force from here on.
167    MetronomeMark(MetronomeMark),
168    /// A tempo said in words, `Grave` or `Allegro`.
169    TempoText(TempoText),
170    /// Words written over or under the staff.
171    TextExpression(TextExpression),
172    /// A sign or words saying where to go next, *Fine* or *D.C.*
173    RepeatExpression(RepeatExpression),
174    /// The dynamic in force from here on.
175    Dynamic(Dynamic),
176    /// A chord named over the music. It holds for the time it has been
177    /// given and takes none until then.
178    ChordSymbol(ChordSymbol),
179    /// A stroke with no pitch.
180    Unpitched(Unpitched),
181    /// Several strokes at once.
182    PercussionChord(PercussionChord),
183    /// A barline standing inside a measure rather than at either end of it,
184    /// where a measure's own barlines are kept.
185    Barline(Barline),
186    /// A bounce or a gap in the line of a held pedal, joined by the pedal
187    /// mark it belongs to.
188    PedalObject(PedalObject),
189    /// A letter or number marking a place to rehearse from.
190    RehearsalMark(RehearsalMark),
191    /// A change of tempo written as one note value becoming another. Boxed:
192    /// it holds two tempo marks.
193    MetricModulation(Box<MetricModulation>),
194    /// Where a manuscript's line, page or column breaks.
195    Break(crate::volpiano::Break),
196    /// How the page, a system or a staff is laid out from here on.
197    Layout(crate::layout::Layout),
198    /// Text standing anywhere on a page. Boxed: it carries its style.
199    TextBox(Box<crate::text::TextBox>),
200    /// Another reading of the passage starting here, which takes no time
201    /// itself. Boxed: it holds a stream.
202    Variant(Box<crate::variant::Variant>),
203}
204
205impl StreamElement {
206    /// Returns the assigned duration, if present.
207    ///
208    /// The marks that only say what is in force from a point — a key, a
209    /// metre, a tempo, a dynamic — have none, as they take no time in
210    /// music21 either. A chord symbol has one, of no length until it is
211    /// given the time it holds.
212    pub fn duration(&self) -> Option<&Duration> {
213        match self {
214            Self::Note(note) => note.duration(),
215            Self::Chord(chord) => chord.duration(),
216            Self::Unpitched(stroke) => stroke.duration(),
217            Self::PercussionChord(chord) => chord.duration(),
218            Self::Rest(rest) => Some(rest.duration()),
219            Self::ChordSymbol(symbol) => Some(symbol.duration()),
220            Self::Stream(_)
221            | Self::Clef(_)
222            | Self::Instrument(_)
223            | Self::KeySignature(_)
224            | Self::Key(_)
225            | Self::TimeSignature(_)
226            | Self::MetronomeMark(_)
227            | Self::TempoText(_)
228            | Self::TextExpression(_)
229            | Self::RepeatExpression(_)
230            | Self::Dynamic(_)
231            | Self::Barline(_)
232            | Self::PedalObject(_)
233            | Self::RehearsalMark(_)
234            | Self::MetricModulation(_)
235            | Self::Break(_)
236            | Self::Layout(_)
237            | Self::TextBox(_)
238            | Self::Variant(_) => None,
239        }
240    }
241
242    /// Returns the duration in quarter lengths.
243    ///
244    /// A nested stream is as long as its own contents; a mark takes no time;
245    /// anything else with no duration of its own defaults to a quarter, as
246    /// music21's does.
247    pub fn quarter_length(&self) -> FloatType {
248        match self {
249            Self::Stream(stream) => stream.end_offset(),
250            Self::Clef(_)
251            | Self::Instrument(_)
252            | Self::KeySignature(_)
253            | Self::Key(_)
254            | Self::TimeSignature(_)
255            | Self::MetronomeMark(_)
256            | Self::TempoText(_)
257            | Self::TextExpression(_)
258            | Self::RepeatExpression(_)
259            | Self::Dynamic(_)
260            | Self::Barline(_)
261            | Self::PedalObject(_)
262            | Self::RehearsalMark(_)
263            | Self::MetricModulation(_)
264            | Self::Break(_)
265            | Self::Layout(_)
266            | Self::TextBox(_)
267            | Self::Variant(_) => 0.0,
268            _ => self
269                .duration()
270                .map(Duration::quarter_length)
271                .unwrap_or_else(|| Duration::default().quarter_length()),
272        }
273    }
274
275    /// Returns all pitches contained by this element, a nested stream's
276    /// included.
277    pub fn pitches(&self) -> Vec<Pitch> {
278        match self {
279            Self::Note(note) => vec![note.pitch().clone()],
280            Self::Chord(chord) => chord.pitches(),
281            Self::Stream(stream) => stream.pitches(),
282            Self::PercussionChord(chord) => chord.pitches(),
283            Self::Unpitched(_)
284            | Self::Rest(_)
285            | Self::Clef(_)
286            | Self::Instrument(_)
287            | Self::KeySignature(_)
288            | Self::Key(_)
289            | Self::TimeSignature(_)
290            | Self::MetronomeMark(_)
291            | Self::TempoText(_)
292            | Self::TextExpression(_)
293            | Self::RepeatExpression(_)
294            | Self::Dynamic(_)
295            | Self::ChordSymbol(_)
296            | Self::Barline(_)
297            | Self::PedalObject(_)
298            | Self::RehearsalMark(_)
299            | Self::MetricModulation(_)
300            | Self::Break(_)
301            | Self::Layout(_)
302            | Self::TextBox(_)
303            | Self::Variant(_) => Vec::new(),
304        }
305    }
306
307    /// The stream this element is, when it is one.
308    pub fn as_stream(&self) -> Option<&Stream> {
309        match self {
310            Self::Stream(stream) => Some(stream),
311            _ => None,
312        }
313    }
314
315    /// music21's `classSortOrder`: what comes first among the things standing
316    /// at one offset.
317    pub(crate) fn class_sort_order(&self) -> i32 {
318        match self {
319            Self::TextBox(_) => -31,
320            Self::TextExpression(_) | Self::RehearsalMark(_) => -30,
321            Self::Instrument(_) => -25,
322            Self::Layout(_) => -10,
323            Self::Stream(stream) if stream.kind() == StreamKind::Voice => 5,
324            Self::Stream(_) => -20,
325            Self::Variant(_) => -22,
326            Self::Barline(_) => -5,
327            Self::Clef(_) => 0,
328            Self::MetronomeMark(_) | Self::TempoText(_) | Self::MetricModulation(_) => 1,
329            Self::KeySignature(_) | Self::Key(_) => 2,
330            Self::TimeSignature(_) => 4,
331            Self::Dynamic(_) => 10,
332            // music21's `RomanNumeral` is a `Harmony`, which sorts before
333            // the notes standing at the same offset as a chord symbol
334            // does; a chord carrying a numeral is one of those.
335            Self::ChordSymbol(_) => 19,
336            Self::Chord(chord) if chord.numeral().is_some() => 19,
337            _ => 20,
338        }
339    }
340
341    /// Whether this element sounds — music21's `.notes`, which is notes and
342    /// chords but not rests.
343    pub fn is_note_or_chord(&self) -> bool {
344        matches!(self, Self::Note(_) | Self::Chord(_))
345    }
346
347    /// Returns a transposed copy.
348    ///
349    /// A key signature moves with the music, as music21's does; a metre and
350    /// a tempo do not depend on pitch and are left alone.
351    pub fn transpose(&self, interval: &Interval) -> Result<Self> {
352        match self {
353            Self::Note(note) => {
354                let mut out = note.clone();
355                out.set_pitch(interval.transpose_pitch(note.pitch())?);
356                Ok(Self::Note(out))
357            }
358            Self::Chord(chord) => Ok(Self::Chord(chord.transpose(interval)?)),
359            Self::Rest(rest) => Ok(Self::Rest(rest.clone())),
360            // A stroke has no pitch to move, and a percussion part is not
361            // transposed with the music.
362            Self::Unpitched(stroke) => Ok(Self::Unpitched(stroke.clone())),
363            Self::PercussionChord(chord) => Ok(Self::PercussionChord(chord.clone())),
364            Self::Stream(stream) => Ok(Self::Stream(Box::new(stream.transpose(interval)?))),
365            Self::Clef(clef) => Ok(Self::Clef(clef.clone())),
366            Self::Instrument(instrument) => Ok(Self::Instrument(instrument.clone())),
367            Self::KeySignature(key) => Ok(Self::KeySignature(key.transpose(interval)?)),
368            Self::Key(key) => Ok(Self::Key(key.transpose(interval)?)),
369            Self::TimeSignature(meter) => Ok(Self::TimeSignature(meter.clone())),
370            Self::MetronomeMark(mark) => Ok(Self::MetronomeMark(mark.clone())),
371            Self::TempoText(text) => Ok(Self::TempoText(text.clone())),
372            Self::TextExpression(text) => Ok(Self::TextExpression(text.clone())),
373            Self::RepeatExpression(mark) => Ok(Self::RepeatExpression(mark.clone())),
374            Self::Dynamic(dynamic) => Ok(Self::Dynamic(dynamic.clone())),
375            Self::ChordSymbol(symbol) => Ok(Self::ChordSymbol(symbol.transpose(interval)?)),
376            Self::Barline(barline) => Ok(Self::Barline(barline.clone())),
377            Self::PedalObject(object) => Ok(Self::PedalObject(object.clone())),
378            Self::RehearsalMark(mark) => Ok(Self::RehearsalMark(mark.clone())),
379            Self::MetricModulation(modulation) => Ok(Self::MetricModulation(modulation.clone())),
380            Self::Break(kind) => Ok(Self::Break(*kind)),
381            Self::Layout(layout) => Ok(Self::Layout(layout.clone())),
382            Self::TextBox(text) => Ok(Self::TextBox(text.clone())),
383            Self::Variant(variant) => Ok(Self::Variant(Box::new(variant.transpose(interval)?))),
384        }
385    }
386}
387
388impl From<Barline> for StreamElement {
389    fn from(value: Barline) -> Self {
390        Self::Barline(value)
391    }
392}
393
394impl From<PedalObject> for StreamElement {
395    fn from(value: PedalObject) -> Self {
396        Self::PedalObject(value)
397    }
398}
399
400impl From<RehearsalMark> for StreamElement {
401    fn from(value: RehearsalMark) -> Self {
402        Self::RehearsalMark(value)
403    }
404}
405
406impl From<MetricModulation> for StreamElement {
407    fn from(value: MetricModulation) -> Self {
408        Self::MetricModulation(Box::new(value))
409    }
410}
411
412impl From<Note> for StreamElement {
413    fn from(value: Note) -> Self {
414        Self::Note(value)
415    }
416}
417
418impl From<Chord> for StreamElement {
419    fn from(value: Chord) -> Self {
420        Self::Chord(value)
421    }
422}
423
424impl From<Rest> for StreamElement {
425    fn from(value: Rest) -> Self {
426        Self::Rest(value)
427    }
428}
429
430impl From<Stream> for StreamElement {
431    fn from(value: Stream) -> Self {
432        Self::Stream(Box::new(value))
433    }
434}
435
436impl From<Clef> for StreamElement {
437    fn from(value: Clef) -> Self {
438        Self::Clef(value)
439    }
440}
441
442impl From<Instrument> for StreamElement {
443    fn from(value: Instrument) -> Self {
444        Self::Instrument(Box::new(value))
445    }
446}
447
448impl From<Key> for StreamElement {
449    fn from(value: Key) -> Self {
450        Self::Key(value)
451    }
452}
453
454impl From<KeySignature> for StreamElement {
455    fn from(value: KeySignature) -> Self {
456        Self::KeySignature(value)
457    }
458}
459
460impl From<TimeSignature> for StreamElement {
461    fn from(value: TimeSignature) -> Self {
462        Self::TimeSignature(value)
463    }
464}
465
466impl From<Dynamic> for StreamElement {
467    fn from(value: Dynamic) -> Self {
468        Self::Dynamic(value)
469    }
470}
471
472impl From<ChordSymbol> for StreamElement {
473    fn from(value: ChordSymbol) -> Self {
474        Self::ChordSymbol(value)
475    }
476}
477
478impl From<TextExpression> for StreamElement {
479    fn from(value: TextExpression) -> Self {
480        Self::TextExpression(value)
481    }
482}
483
484impl From<Unpitched> for StreamElement {
485    fn from(value: Unpitched) -> Self {
486        Self::Unpitched(value)
487    }
488}
489
490impl From<PercussionChord> for StreamElement {
491    fn from(value: PercussionChord) -> Self {
492        Self::PercussionChord(value)
493    }
494}
495
496impl From<RepeatExpression> for StreamElement {
497    fn from(value: RepeatExpression) -> Self {
498        Self::RepeatExpression(value)
499    }
500}
501
502impl From<TempoText> for StreamElement {
503    fn from(value: TempoText) -> Self {
504        Self::TempoText(value)
505    }
506}
507
508impl From<MetronomeMark> for StreamElement {
509    fn from(value: MetronomeMark) -> Self {
510        Self::MetronomeMark(value)
511    }
512}
513
514/// A timestamped stream item.
515#[derive(Clone, Debug)]
516#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
517pub struct StreamEvent {
518    offset: FloatType,
519    element: StreamElement,
520}
521
522impl StreamEvent {
523    /// Creates an event at an offset measured in quarter lengths.
524    pub fn new(offset: FloatType, element: impl Into<StreamElement>) -> Self {
525        Self {
526            offset,
527            element: element.into(),
528        }
529    }
530
531    /// Returns the offset in quarter lengths.
532    pub fn offset(&self) -> FloatType {
533        self.offset
534    }
535
536    /// Returns the stream element.
537    pub fn element_mut(&mut self) -> &mut StreamElement {
538        &mut self.element
539    }
540
541    /// The element itself.
542    pub fn element(&self) -> &StreamElement {
543        &self.element
544    }
545
546    /// The offset just past this element.
547    pub fn end_offset(&self) -> FloatType {
548        self.offset + self.element.quarter_length()
549    }
550}
551
552/// An ordered stream of music, which may hold other streams.
553#[derive(Clone, Debug, Default)]
554#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
555#[must_use]
556pub struct Stream {
557    #[cfg_attr(feature = "serde", serde(default))]
558    kind: StreamKind,
559    events: Vec<StreamEvent>,
560    #[cfg_attr(feature = "serde", serde(default))]
561    labels: Labels,
562}
563
564/// How a staff group's barlines are drawn: music21's `barTogether`.
565#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
566#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
567pub enum BarTogether {
568    /// Barlines run through every staff of the group.
569    Yes,
570    /// Each staff is barred on its own.
571    No,
572    /// Barlines run between the staves but not through them.
573    Mensurstrich,
574}
575
576impl BarTogether {
577    /// The group barline MusicXML writes for it.
578    pub fn as_str(self) -> &'static str {
579        match self {
580            Self::Yes => "yes",
581            Self::No => "no",
582            Self::Mensurstrich => "Mensurstrich",
583        }
584    }
585}
586
587/// Parts of a score bracketed together: music21's `layout.StaffGroup`,
588/// which holds the parts it spans.
589///
590/// The parts are named by where they stand among the score's parts, first
591/// to last, in the order the group was given them.
592#[derive(Clone, Debug, PartialEq, Eq)]
593#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
594pub struct StaffGroup {
595    parts: Vec<usize>,
596    name: Option<String>,
597    abbreviation: Option<String>,
598    symbol: Option<String>,
599    bar_together: Option<BarTogether>,
600    name_hidden: bool,
601}
602
603impl StaffGroup {
604    /// A group of the parts at these positions, barred together and drawn
605    /// with no symbol, as music21's starts out.
606    pub fn new(parts: Vec<usize>) -> Self {
607        Self {
608            parts,
609            name: None,
610            abbreviation: None,
611            symbol: None,
612            bar_together: Some(BarTogether::Yes),
613            name_hidden: false,
614        }
615    }
616
617    /// The positions of the parts the group spans.
618    pub fn parts(&self) -> &[usize] {
619        &self.parts
620    }
621
622    /// The group's name.
623    pub fn name(&self) -> Option<&str> {
624        self.name.as_deref()
625    }
626
627    /// Names the group, or clears the name.
628    pub fn set_name(&mut self, name: Option<String>) {
629        self.name = name;
630    }
631
632    /// The group's short name.
633    pub fn abbreviation(&self) -> Option<&str> {
634        self.abbreviation.as_deref()
635    }
636
637    /// Sets the short name, or clears it.
638    pub fn set_abbreviation(&mut self, abbreviation: Option<String>) {
639        self.abbreviation = abbreviation;
640    }
641
642    /// What the group is drawn with: `bracket`, `brace`, `line` or `square`.
643    pub fn symbol(&self) -> Option<&str> {
644        self.symbol.as_deref()
645    }
646
647    /// Sets what the group is drawn with. As in music21, `none` in any case
648    /// clears it, and anything but the four symbols is refused.
649    pub fn set_symbol(&mut self, symbol: Option<&str>) -> Result<()> {
650        self.symbol = match symbol.map(str::to_lowercase) {
651            None => None,
652            Some(symbol) if symbol == "none" => None,
653            Some(symbol) if ["brace", "line", "bracket", "square"].contains(&symbol.as_str()) => {
654                Some(symbol)
655            }
656            Some(symbol) => {
657                return Err(crate::error::Error::Value(format!(
658                    "the symbol value {symbol} is not acceptable"
659                )));
660            }
661        };
662        Ok(())
663    }
664
665    /// How the group's barlines are drawn, where that has been said.
666    pub fn bar_together(&self) -> Option<BarTogether> {
667        self.bar_together
668    }
669
670    /// Says how the group's barlines are drawn.
671    pub fn set_bar_together(&mut self, bar_together: Option<BarTogether>) {
672        self.bar_together = bar_together;
673    }
674
675    /// Whether the name is left unprinted: music21's `hideObjectOnPrint`.
676    pub fn name_hidden(&self) -> bool {
677        self.name_hidden
678    }
679
680    /// Says whether the name is left unprinted.
681    pub fn set_name_hidden(&mut self, hidden: bool) {
682        self.name_hidden = hidden;
683    }
684}
685
686/// What a stream is called and numbered, as distinct from what it holds.
687///
688/// music21 spreads these over its subclasses: a measure has a number, a part
689/// a name. They are kept together here, and a stream of a kind that has no
690/// use for one simply leaves it unset.
691#[derive(Clone, Debug, Default, PartialEq)]
692#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
693struct Labels {
694    number: IntegerType,
695    number_suffix: Option<String>,
696    number_hidden: bool,
697    id: Option<String>,
698    name: Option<String>,
699    abbreviation: Option<String>,
700    name_hidden: bool,
701    abbreviation_hidden: bool,
702    /// Boxed: most streams carry none.
703    metadata: Option<Box<Metadata>>,
704    staff_groups: Vec<StaffGroup>,
705    left_barline: Option<Barline>,
706    right_barline: Option<Barline>,
707    spanners: Vec<Spanner>,
708    ending: Option<Ending>,
709    #[cfg_attr(feature = "serde", serde(default))]
710    padding_left: FloatType,
711    #[cfg_attr(feature = "serde", serde(default))]
712    padding_right: FloatType,
713    /// music21's `atSoundingPitch`, `None` for its `'unknown'`.
714    #[cfg_attr(feature = "serde", serde(default))]
715    at_sounding_pitch: Option<bool>,
716    #[cfg_attr(feature = "serde", serde(default))]
717    measure_numbering: Option<String>,
718}
719
720impl Stream {
721    /// Creates an empty stream.
722    pub fn new() -> Self {
723        Self::default()
724    }
725
726    /// Creates an empty stream standing for one of music21's subclasses.
727    pub fn with_kind(kind: StreamKind) -> Self {
728        Self {
729            kind,
730            ..Self::default()
731        }
732    }
733
734    /// A measure's number: music21's `Measure.number`, which is nought until
735    /// something numbers it.
736    pub fn number(&self) -> IntegerType {
737        self.labels.number
738    }
739
740    /// Numbers the measure.
741    pub fn set_number(&mut self, number: IntegerType) {
742        self.labels.number = number;
743    }
744
745    /// What follows the number, as the `a` of a measure numbered `12a`:
746    /// music21's `numberSuffix`.
747    pub fn number_suffix(&self) -> Option<&str> {
748        self.labels.number_suffix.as_deref()
749    }
750
751    /// Sets what follows the number, or clears it.
752    pub fn set_number_suffix(&mut self, suffix: Option<String>) {
753        self.labels.number_suffix = suffix;
754    }
755
756    /// The number with its suffix, `12a`: music21's
757    /// `measureNumberWithSuffix`.
758    pub fn number_with_suffix(&self) -> String {
759        format!(
760            "{}{}",
761            self.labels.number,
762            self.labels.number_suffix.as_deref().unwrap_or("")
763        )
764    }
765
766    /// Whether the measure's number is left unshown, as a pickup bar's is:
767    /// music21's `showNumber` set to `NEVER`.
768    pub fn number_hidden(&self) -> bool {
769        self.labels.number_hidden
770    }
771
772    /// Says whether the measure's number is left unshown.
773    pub fn set_number_hidden(&mut self, hidden: bool) {
774        self.labels.number_hidden = hidden;
775    }
776
777    /// Which measures' numbers are shown from this measure on, as MusicXML's
778    /// `<measure-numbering>` says it -- `none`, `measure` or `system`:
779    /// music21's `style.measureNumbering`. How the numbers are drawn is not
780    /// kept.
781    pub fn measure_numbering(&self) -> Option<&str> {
782        self.labels.measure_numbering.as_deref()
783    }
784
785    /// Says which measures' numbers are shown from this measure on.
786    pub fn set_measure_numbering(&mut self, numbering: Option<String>) {
787        self.labels.measure_numbering = numbering;
788    }
789
790    /// The name the stream is known by, as a part's `P1`: music21's `id`
791    /// where one was given rather than taken from a memory address.
792    pub fn id(&self) -> Option<&str> {
793        self.labels.id.as_deref()
794    }
795
796    /// Sets the stream's id, or clears it.
797    pub fn set_id(&mut self, id: Option<String>) {
798        self.labels.id = id;
799    }
800
801    /// A part's name, as printed beside its first system: music21's
802    /// `partName`.
803    pub fn name(&self) -> Option<&str> {
804        self.labels.name.as_deref()
805    }
806
807    /// Names the part, or clears the name.
808    pub fn set_name(&mut self, name: Option<String>) {
809        self.labels.name = name;
810    }
811
812    /// A part's short name, as printed beside the systems after the first:
813    /// music21's `partAbbreviation`.
814    pub fn abbreviation(&self) -> Option<&str> {
815        self.labels.abbreviation.as_deref()
816    }
817
818    /// Sets the part's short name, or clears it.
819    pub fn set_abbreviation(&mut self, abbreviation: Option<String>) {
820        self.labels.abbreviation = abbreviation;
821    }
822
823    /// Whether the part's name is left unprinted: music21's
824    /// `style.printPartName` set to false.
825    pub fn name_hidden(&self) -> bool {
826        self.labels.name_hidden
827    }
828
829    /// Says whether the part's name is left unprinted.
830    pub fn set_name_hidden(&mut self, hidden: bool) {
831        self.labels.name_hidden = hidden;
832    }
833
834    /// Whether the part's short name is left unprinted: music21's
835    /// `style.printPartAbbreviation` set to false.
836    pub fn abbreviation_hidden(&self) -> bool {
837        self.labels.abbreviation_hidden
838    }
839
840    /// Says whether the part's short name is left unprinted.
841    pub fn set_abbreviation_hidden(&mut self, hidden: bool) {
842        self.labels.abbreviation_hidden = hidden;
843    }
844
845    /// The title, composer and the rest a score carries: music21's
846    /// `metadata`.
847    pub fn metadata(&self) -> Option<&Metadata> {
848        self.labels.metadata.as_deref()
849    }
850
851    /// Sets the metadata, or clears it.
852    pub fn set_metadata(&mut self, metadata: Option<Metadata>) {
853        self.labels.metadata = metadata.map(Box::new);
854    }
855
856    /// The groups a score brackets its parts in, in the order they were
857    /// added.
858    pub fn staff_groups(&self) -> &[StaffGroup] {
859        &self.labels.staff_groups
860    }
861
862    /// Brackets some of the score's parts together.
863    pub fn add_staff_group(&mut self, group: StaffGroup) {
864        self.labels.staff_groups.push(group);
865    }
866
867    /// The barline a measure starts with, where it is not an ordinary one:
868    /// music21's `leftBarline`.
869    pub fn left_barline(&self) -> Option<&Barline> {
870        self.labels.left_barline.as_ref()
871    }
872
873    /// Sets the barline a measure starts with, or clears it.
874    pub fn set_left_barline(&mut self, barline: Option<Barline>) {
875        self.labels.left_barline = barline;
876    }
877
878    /// The barline a measure ends with, where it is not an ordinary one:
879    /// music21's `rightBarline`.
880    pub fn right_barline(&self) -> Option<&Barline> {
881        self.labels.right_barline.as_ref()
882    }
883
884    /// Sets the barline a measure ends with, or clears it.
885    pub fn set_right_barline(&mut self, barline: Option<Barline>) {
886        self.labels.right_barline = barline;
887    }
888
889    /// How much of a measure's bar goes unfilled before its first note, as
890    /// a pickup leaves the start of its bar: music21's `paddingLeft`.
891    pub fn padding_left(&self) -> FloatType {
892        self.labels.padding_left
893    }
894
895    /// Says how much of the bar goes unfilled before the first note.
896    pub fn set_padding_left(&mut self, padding: FloatType) {
897        self.labels.padding_left = padding;
898    }
899
900    /// How much of a measure's bar goes unfilled after its last note, as a
901    /// measure cut short leaves its end: music21's `paddingRight`.
902    pub fn padding_right(&self) -> FloatType {
903        self.labels.padding_right
904    }
905
906    /// Says how much of the bar goes unfilled after the last note.
907    pub fn set_padding_right(&mut self, padding: FloatType) {
908        self.labels.padding_right = padding;
909    }
910
911    /// The alternative ending a measure is part of, where it is in one.
912    pub fn ending(&self) -> Option<&Ending> {
913        self.labels.ending.as_ref()
914    }
915
916    /// Puts the measure in an alternative ending, or takes it out.
917    pub fn set_ending(&mut self, ending: Option<Ending>) {
918        self.labels.ending = ending;
919    }
920
921    /// The slurs and other spanners this stream holds, each naming what it
922    /// joins by position in this stream's [`Stream::leaves`].
923    pub fn spanners(&self) -> &[Spanner] {
924        &self.labels.spanners
925    }
926
927    /// Adds a spanner, naming what it joins by position in this stream's
928    /// [`Stream::leaves`].
929    pub fn add_spanner(&mut self, spanner: Spanner) {
930        self.labels.spanners.push(spanner);
931    }
932
933    /// Takes every spanner off this stream.
934    pub(crate) fn clear_spanners(&mut self) {
935        self.labels.spanners.clear();
936    }
937
938    /// Which of music21's `Stream` subclasses this stands for.
939    pub fn kind(&self) -> StreamKind {
940        self.kind
941    }
942
943    /// Sets which subclass this stands for.
944    pub fn set_kind(&mut self, kind: StreamKind) {
945        self.kind = kind;
946    }
947
948    /// This stream holding other events, in the order given: its kind, name
949    /// and numbers kept, its spanners dropped, since the places they name
950    /// are gone.
951    pub(crate) fn with_events(&self, events: Vec<StreamEvent>) -> Self {
952        let mut labels = self.labels.clone();
953        labels.spanners.clear();
954        Self {
955            kind: self.kind,
956            events,
957            labels,
958        }
959    }
960
961    /// Creates a stream from events, sorted by offset.
962    pub fn from_events(events: impl IntoIterator<Item = StreamEvent>) -> Self {
963        let mut stream = Self {
964            events: events.into_iter().collect(),
965            ..Self::default()
966        };
967        stream.sort_events();
968        stream
969    }
970
971    /// Inserts an element at a quarter-length offset.
972    pub fn insert(&mut self, offset: FloatType, element: impl Into<StreamElement>) {
973        self.events.push(StreamEvent::new(offset, element));
974        self.sort_events();
975    }
976
977    /// Appends an element after the current end of the stream.
978    pub fn push(&mut self, element: impl Into<StreamElement>) {
979        let element = element.into();
980        let offset = self.end_offset();
981        self.events.push(StreamEvent::new(offset, element));
982    }
983
984    /// Returns immutable events in offset order.
985    pub fn events_mut(&mut self) -> &mut [StreamEvent] {
986        &mut self.events
987    }
988
989    /// The events in offset order.
990    pub fn events(&self) -> &[StreamEvent] {
991        &self.events
992    }
993
994    /// Iterates over events in offset order.
995    pub fn iter(&self) -> impl Iterator<Item = &StreamEvent> {
996        self.events.iter()
997    }
998
999    /// How many events this stream holds directly, not counting what any
1000    /// nested stream holds.
1001    pub fn len(&self) -> usize {
1002        self.events.len()
1003    }
1004
1005    /// Whether this stream holds nothing at all.
1006    pub fn is_empty(&self) -> bool {
1007        self.events.is_empty()
1008    }
1009
1010    /// One timeline with the nesting dissolved: music21's `flatten`.
1011    ///
1012    /// Each nested stream's offset is added to its contents', and the
1013    /// streams themselves are gone; everything else comes through in
1014    /// music21's order: by offset, then at one offset by class -- a clef
1015    /// before a key before a dynamic before a chord symbol before a note --
1016    /// with grace notes first among their class, and otherwise as the
1017    /// nesting held them, part by part.
1018    pub fn flatten(&self) -> Self {
1019        let mut flattened = Self::with_kind(self.kind);
1020        self.flatten_into(0.0, &mut flattened.events);
1021        // music21 sorts what stands at one offset by its class order --
1022        // a dynamic before a chord symbol before a note -- and a grace note
1023        // before the rest of its class, and otherwise keeps the order the
1024        // walk met them in.
1025        flattened.events.sort_by(|left, right| {
1026            left.offset
1027                .partial_cmp(&right.offset)
1028                .unwrap_or(std::cmp::Ordering::Equal)
1029                .then_with(|| {
1030                    left.element
1031                        .class_sort_order()
1032                        .cmp(&right.element.class_sort_order())
1033                })
1034                .then_with(|| is_grace(&right.element).cmp(&is_grace(&left.element)))
1035        });
1036        flattened
1037    }
1038
1039    fn flatten_into(&self, base: FloatType, out: &mut Vec<StreamEvent>) {
1040        for event in &self.events {
1041            // Summed as music21 sums them, snapped by `opFrac`, so three
1042            // triplets end on the beat however deep they sit.
1043            let offset = crate::makenotation::op_frac(base + event.offset);
1044            match &event.element {
1045                StreamElement::Stream(stream) => stream.flatten_into(offset, out),
1046                element => out.push(StreamEvent::new(offset, element.clone())),
1047            }
1048        }
1049    }
1050
1051    /// Every element at its offset from this stream's start, nested streams
1052    /// themselves included: music21's `recurse`.
1053    pub fn recurse(&self) -> Vec<(FloatType, &StreamElement)> {
1054        let mut out = Vec::new();
1055        self.recurse_into(0.0, &mut out);
1056        out
1057    }
1058
1059    fn recurse_into<'a>(&'a self, base: FloatType, out: &mut Vec<(FloatType, &'a StreamElement)>) {
1060        for event in &self.events {
1061            // Summed as music21 sums them, snapped by `opFrac`, so three
1062            // triplets end on the beat however deep they sit.
1063            let offset = crate::makenotation::op_frac(base + event.offset);
1064            out.push((offset, &event.element));
1065            if let StreamElement::Stream(stream) = &event.element {
1066                stream.recurse_into(offset, out);
1067            }
1068        }
1069    }
1070
1071    /// Every element that is not itself a stream, at its offset from this
1072    /// stream's start, in the order [`Stream::for_each_mut`] hands them over.
1073    ///
1074    /// An element's index in this list is its *position*, which is how the
1075    /// walks answering about particular elements say which they mean:
1076    /// [`crate::volume::dynamics_in_force`],
1077    /// [`crate::chordsymbol::chord_symbol_durations`],
1078    /// [`crate::voiceleading::voice_leading_quartet_positions`] and
1079    /// [`crate::voiceleading::verticality_positions_at`]. A caller keeping
1080    /// something of its own beside each element, as a binding keeps the
1081    /// object it was handed, finds it again by the same index.
1082    pub fn leaves(&self) -> Vec<(FloatType, &StreamElement)> {
1083        self.leaves_under_top()
1084            .into_iter()
1085            .map(|(_, offset, element)| (offset, element))
1086            .collect()
1087    }
1088
1089    /// [`Stream::leaves`], each with the index of the event of this stream it
1090    /// came out of: itself for an element held directly, the nested stream
1091    /// holding it otherwise.
1092    pub(crate) fn leaves_under_top(&self) -> Vec<(usize, FloatType, &StreamElement)> {
1093        let mut out = Vec::new();
1094        for (top, event) in self.events.iter().enumerate() {
1095            match &event.element {
1096                StreamElement::Stream(stream) => {
1097                    let mut inner = Vec::new();
1098                    stream.leaves_into(event.offset, &mut inner);
1099                    out.extend(
1100                        inner
1101                            .into_iter()
1102                            .map(|(offset, element)| (top, offset, element)),
1103                    );
1104                }
1105                element => out.push((top, event.offset, element)),
1106            }
1107        }
1108        out
1109    }
1110
1111    /// The positions among [`Stream::leaves`] in the order
1112    /// [`Stream::flatten`] puts them: by offset, then by class order, a
1113    /// grace note ahead of the rest of its class, and otherwise as the walk
1114    /// met them.
1115    ///
1116    /// The two walks are the same walk, so the *n*th leaf is the *n*th
1117    /// element the flattening read; this says where each of those stands
1118    /// once sorted, which is how a walk reading a flattened stream answers
1119    /// in positions a caller can look up.
1120    pub(crate) fn flatten_order(leaves: &[(FloatType, &StreamElement)]) -> Vec<usize> {
1121        let mut order: Vec<usize> = (0..leaves.len()).collect();
1122        order.sort_by(|left, right| {
1123            let (left_offset, left_element) = leaves[*left];
1124            let (right_offset, right_element) = leaves[*right];
1125            left_offset
1126                .total_cmp(&right_offset)
1127                .then(
1128                    left_element
1129                        .class_sort_order()
1130                        .cmp(&right_element.class_sort_order()),
1131                )
1132                .then(is_grace(right_element).cmp(&is_grace(left_element)))
1133        });
1134        order
1135    }
1136
1137    fn leaves_into<'a>(&'a self, base: FloatType, out: &mut Vec<(FloatType, &'a StreamElement)>) {
1138        for event in &self.events {
1139            // Summed as music21 sums them, snapped by `opFrac`, so three
1140            // triplets end on the beat however deep they sit.
1141            let offset = crate::makenotation::op_frac(base + event.offset);
1142            match &event.element {
1143                StreamElement::Stream(stream) => stream.leaves_into(offset, out),
1144                element => out.push((offset, element)),
1145            }
1146        }
1147    }
1148
1149    /// Takes out one of this stream's own events, and with it whatever it
1150    /// holds: music21's `remove`. Every spanner, here or in a nested
1151    /// stream, is moved to where what it names now stands, and names
1152    /// nothing for an element taken out. Nothing is taken out for a place
1153    /// past the end.
1154    pub fn remove_event(&mut self, index: usize) -> Option<StreamEvent> {
1155        if index >= self.events.len() {
1156            return None;
1157        }
1158        let under = self.leaves_under_top();
1159        let doomed: Vec<usize> = under
1160            .iter()
1161            .enumerate()
1162            .filter(|(_, (top, _, _))| *top == index)
1163            .map(|(position, _)| position)
1164            .collect();
1165        let holds_a_stream = matches!(self.events[index].element, StreamElement::Stream(_));
1166        if holds_a_stream {
1167            self.retain_leaves(&mut |position, _| !doomed.contains(&position));
1168            return Some(self.events.remove(index));
1169        }
1170        let removed = self.events[index].clone();
1171        self.retain_leaves(&mut |position, _| !doomed.contains(&position));
1172        Some(removed)
1173    }
1174
1175    /// Hands every element to a closure with its offset from this stream's
1176    /// start, nested streams' contents included, so that it may be changed
1177    /// where it sits.
1178    ///
1179    /// [`Stream::flatten`] and [`Stream::recurse`] hand back copies and
1180    /// references; this is the walk for an edit that has to land in the
1181    /// score itself. Things at one offset come in the same order `flatten`
1182    /// gives them. A nested stream is walked into rather than handed over.
1183    pub fn for_each_mut(&mut self, visit: &mut impl FnMut(FloatType, &mut StreamElement)) {
1184        self.for_each_mut_from(0.0, visit);
1185    }
1186
1187    fn for_each_mut_from(
1188        &mut self,
1189        base: FloatType,
1190        visit: &mut impl FnMut(FloatType, &mut StreamElement),
1191    ) {
1192        for event in &mut self.events {
1193            // Summed as music21 sums them, snapped by `opFrac`, so three
1194            // triplets end on the beat however deep they sit.
1195            let offset = crate::makenotation::op_frac(base + event.offset);
1196            match &mut event.element {
1197                StreamElement::Stream(stream) => stream.for_each_mut_from(offset, visit),
1198                element => visit(offset, element),
1199            }
1200        }
1201    }
1202
1203    /// Keeps the leaves `keep` accepts, handed each with its position in
1204    /// [`Stream::leaves`] to change as it likes, and drops the rest. Every
1205    /// spanner, here or in a nested stream, is moved to where what it names
1206    /// now stands, and names nothing for an element dropped.
1207    pub fn retain_leaves(&mut self, keep: &mut impl FnMut(usize, &mut StreamElement) -> bool) {
1208        let mut seen = 0;
1209        self.retain_leaves_from(&mut seen, keep);
1210    }
1211
1212    /// Puts `replacement` in place of the stream reached by `path`, the
1213    /// index of an event holding a stream at each level down from here.
1214    /// Every spanner of a stream on the way moves past what was replaced
1215    /// to where it now stands, and names nothing for an element replaced.
1216    pub(crate) fn replace_nested(&mut self, path: &[usize], replacement: Stream) {
1217        self.edit_nested(path, |target| {
1218            let gone = vec![None; target.leaf_total()];
1219            *target = replacement;
1220            ((), gone)
1221        });
1222    }
1223
1224    /// Edits the stream reached by `path`, the index of an event holding a
1225    /// stream at each level down from here. `edit` answers what it answers
1226    /// and where each of the stream's leaves went, by old position, having
1227    /// moved that stream's own spanners itself; every spanner of a stream on
1228    /// the way is moved with them. The answer is `edit`'s, and where each of
1229    /// this stream's leaves went.
1230    pub(crate) fn edit_nested<R>(
1231        &mut self,
1232        path: &[usize],
1233        edit: impl FnOnce(&mut Stream) -> (R, Vec<Option<usize>>),
1234    ) -> (R, Vec<Option<usize>>) {
1235        let Some((&first, rest)) = path.split_first() else {
1236            return edit(self);
1237        };
1238        let total = self.leaf_total();
1239        let before: usize = self.events[..first]
1240            .iter()
1241            .map(|event| leaf_count(&event.element))
1242            .sum();
1243        let StreamElement::Stream(inner) = &mut self.events[first].element else {
1244            return edit(self);
1245        };
1246        let old = inner.leaf_total();
1247        let (answer, inner_moved) = inner.edit_nested(rest, edit);
1248        let new = inner.leaf_total();
1249        let moved: Vec<Option<usize>> = (0..total)
1250            .map(|place| {
1251                if place < before {
1252                    Some(place)
1253                } else if place < before + old {
1254                    inner_moved
1255                        .get(place - before)
1256                        .copied()
1257                        .flatten()
1258                        .map(|at| at + before)
1259                } else {
1260                    Some(place - old + new)
1261                }
1262            })
1263            .collect();
1264        for spanner in &mut self.labels.spanners {
1265            spanner.move_places(&moved);
1266        }
1267        (answer, moved)
1268    }
1269
1270    /// How many leaves this stream has.
1271    pub(crate) fn leaf_total(&self) -> usize {
1272        self.events
1273            .iter()
1274            .map(|event| leaf_count(&event.element))
1275            .sum()
1276    }
1277
1278    /// Puts `events` in place of this stream's own, in the order given,
1279    /// each with the index of the event it stood at here, if it did. Every
1280    /// spanner of this stream is moved to where what it names now stands,
1281    /// and names nothing for an element no longer here. The answer is where
1282    /// each leaf went, by old position.
1283    pub(crate) fn replace_events(
1284        &mut self,
1285        events: Vec<(StreamEvent, Option<usize>)>,
1286    ) -> Vec<Option<usize>> {
1287        let mut starts = Vec::with_capacity(self.events.len());
1288        let mut first = 0;
1289        for event in &self.events {
1290            starts.push(first);
1291            first += leaf_count(&event.element);
1292        }
1293        let mut moved: Vec<Option<usize>> = vec![None; first];
1294        let mut placed = 0;
1295        for (event, origin) in &events {
1296            let count = leaf_count(&event.element);
1297            if let Some(&start) = origin.and_then(|origin| starts.get(origin)) {
1298                for leaf in 0..count {
1299                    if let Some(slot) = moved.get_mut(start + leaf) {
1300                        *slot = Some(placed + leaf);
1301                    }
1302                }
1303            }
1304            placed += count;
1305        }
1306        self.events = events.into_iter().map(|(event, _)| event).collect();
1307        for spanner in &mut self.labels.spanners {
1308            spanner.move_places(&moved);
1309        }
1310        moved
1311    }
1312
1313    /// Adds events to this stream's own and puts them all in the order
1314    /// music21 sorts a stream in, an added event after one already here that
1315    /// sorts alike. Every spanner of this stream is moved to where what it
1316    /// names now stands. The answer is where each leaf went, by old
1317    /// position.
1318    pub(crate) fn insert_sorted(&mut self, added: Vec<StreamEvent>) -> Vec<Option<usize>> {
1319        // Each event held here with where its leaves started; nothing for
1320        // one added.
1321        let mut first = 0;
1322        let mut held: Vec<(StreamEvent, Option<usize>)> = Vec::new();
1323        for event in std::mem::take(&mut self.events) {
1324            let count = leaf_count(&event.element);
1325            held.push((event, Some(first)));
1326            first += count;
1327        }
1328        held.extend(added.into_iter().map(|event| (event, None)));
1329        held.sort_by(|left, right| crate::makenotation::event_order(&left.0, &right.0));
1330        let mut moved: Vec<Option<usize>> = vec![None; first];
1331        let mut placed = 0;
1332        for (event, start) in &held {
1333            let count = leaf_count(&event.element);
1334            if let Some(start) = start {
1335                for offset in 0..count {
1336                    moved[start + offset] = Some(placed + offset);
1337                }
1338            }
1339            placed += count;
1340        }
1341        self.events = held.into_iter().map(|(event, _)| event).collect();
1342        for spanner in &mut self.labels.spanners {
1343            spanner.move_places(&moved);
1344        }
1345        moved
1346    }
1347
1348    /// [`Stream::retain_leaves`] below the `seen` leaves already walked; the
1349    /// answer is where each of this stream's leaves went, by old position.
1350    fn retain_leaves_from(
1351        &mut self,
1352        seen: &mut usize,
1353        keep: &mut impl FnMut(usize, &mut StreamElement) -> bool,
1354    ) -> Vec<Option<usize>> {
1355        let mut moved: Vec<Option<usize>> = Vec::new();
1356        let mut kept = 0;
1357        self.events.retain_mut(|event| match &mut event.element {
1358            StreamElement::Stream(inner) => {
1359                let inner_moved = inner.retain_leaves_from(seen, keep);
1360                let count = inner_moved.iter().flatten().count();
1361                moved.extend(
1362                    inner_moved
1363                        .into_iter()
1364                        .map(|place| place.map(|place| place + kept)),
1365                );
1366                kept += count;
1367                true
1368            }
1369            element => {
1370                let position = *seen;
1371                *seen += 1;
1372                if keep(position, element) {
1373                    moved.push(Some(kept));
1374                    kept += 1;
1375                    true
1376                } else {
1377                    moved.push(None);
1378                    false
1379                }
1380            }
1381        });
1382        for spanner in &mut self.labels.spanners {
1383            spanner.move_places(&moved);
1384        }
1385        moved
1386    }
1387
1388    /// Whether this stream holds parts, or streams standing in for them:
1389    /// music21's `hasPartLikeStreams`. A part says so; a measure or a voice,
1390    /// or a stream starting anywhere but the beginning, says not; any other
1391    /// stream holding measures or notes and rests says so, unless a later
1392    /// one says not.
1393    pub fn has_part_like_streams(&self) -> bool {
1394        let mut part_like = false;
1395        for event in &self.events {
1396            let Some(stream) = event.element.as_stream() else {
1397                continue;
1398            };
1399            match stream.kind {
1400                StreamKind::Part | StreamKind::PartStaff => return true,
1401                StreamKind::Measure | StreamKind::Voice => return false,
1402                _ if event.offset != 0.0 => return false,
1403                _ => {}
1404            }
1405            let holds_music = stream.events.iter().any(|inner| {
1406                inner.element.is_instance("GeneralNote")
1407                    || inner
1408                        .element
1409                        .as_stream()
1410                        .is_some_and(|nested| nested.kind == StreamKind::Measure)
1411            });
1412            if holds_music {
1413                part_like = true;
1414            }
1415        }
1416        part_like
1417    }
1418
1419    /// The streams of one kind held directly by this one: music21's `.parts`
1420    /// on a score, `.measures` on a part, `.voices` on a measure.
1421    pub fn streams_of_kind(&self, kind: StreamKind) -> Vec<&Stream> {
1422        self.events
1423            .iter()
1424            .filter_map(|event| event.element.as_stream())
1425            .filter(|stream| stream.kind == kind)
1426            .collect()
1427    }
1428
1429    /// The parts this stream holds, a staff of a part written on several
1430    /// included: music21's `.parts`, which a `PartStaff` is one of.
1431    pub fn parts(&self) -> Vec<&Stream> {
1432        self.events
1433            .iter()
1434            .filter_map(|event| event.element.as_stream())
1435            .filter(|stream| matches!(stream.kind, StreamKind::Part | StreamKind::PartStaff))
1436            .collect()
1437    }
1438
1439    /// The measures this stream holds.
1440    pub fn measures(&self) -> Vec<&Stream> {
1441        self.streams_of_kind(StreamKind::Measure)
1442    }
1443
1444    /// The voices this stream holds.
1445    pub fn voices(&self) -> Vec<&Stream> {
1446        self.streams_of_kind(StreamKind::Voice)
1447    }
1448
1449    /// Every note and chord on the flattened timeline: music21's
1450    /// `flatten().notes`, which leaves rests out.
1451    pub fn notes(&self) -> Vec<(FloatType, StreamElement)> {
1452        self.flatten()
1453            .events
1454            .into_iter()
1455            .filter(|event| event.element.is_note_or_chord())
1456            .map(|event| (event.offset, event.element))
1457            .collect()
1458    }
1459
1460    /// Returns the maximum event end offset, a nested stream's own length
1461    /// included, snapped to the fraction it stands for: music21's
1462    /// `highestTime`.
1463    pub fn end_offset(&self) -> FloatType {
1464        crate::makenotation::op_frac(
1465            self.events
1466                .iter()
1467                .map(StreamEvent::end_offset)
1468                .fold(0.0, FloatType::max),
1469        )
1470    }
1471
1472    /// Returns all pitches in timeline order, from nested streams too.
1473    pub fn pitches(&self) -> Vec<Pitch> {
1474        self.flatten()
1475            .events
1476            .iter()
1477            .flat_map(|event| event.element.pitches())
1478            .collect()
1479    }
1480
1481    /// The key signature in force at an offset: the last one written at or
1482    /// before it, anywhere in the nesting.
1483    ///
1484    /// This is what music21 answers with `getContextByClass(KeySignature)`,
1485    /// found by looking back along the flattened timeline rather than by
1486    /// walking the sites an object belongs to.
1487    pub fn key_signature_at(&self, offset: FloatType) -> Option<KeySignature> {
1488        self.in_force_at(offset, |element| match element {
1489            StreamElement::KeySignature(key) => Some(key.clone()),
1490            StreamElement::Key(key) => Some(key.key_signature()),
1491            _ => None,
1492        })
1493    }
1494
1495    /// The metre in force at an offset, found the same way.
1496    pub fn time_signature_at(&self, offset: FloatType) -> Option<TimeSignature> {
1497        self.in_force_at(offset, |element| match element {
1498            StreamElement::TimeSignature(meter) => Some(meter.clone()),
1499            _ => None,
1500        })
1501    }
1502
1503    /// The tempo in force at an offset, found the same way.
1504    pub fn metronome_mark_at(&self, offset: FloatType) -> Option<MetronomeMark> {
1505        self.in_force_at(offset, |element| match element {
1506            StreamElement::MetronomeMark(mark) => Some(mark.clone()),
1507            _ => None,
1508        })
1509    }
1510
1511    /// The last thing of one sort written at or before an offset.
1512    fn in_force_at<T>(
1513        &self,
1514        offset: FloatType,
1515        read: impl Fn(&StreamElement) -> Option<T>,
1516    ) -> Option<T> {
1517        self.flatten()
1518            .events
1519            .iter()
1520            .take_while(|event| event.offset <= offset)
1521            .filter_map(|event| read(&event.element))
1522            .last()
1523    }
1524
1525    /// Returns a transposed copy, nesting and all.
1526    pub fn transpose(&self, interval: &Interval) -> Result<Self> {
1527        let events = self
1528            .events
1529            .iter()
1530            .map(|event| {
1531                Ok(StreamEvent::new(
1532                    event.offset,
1533                    event.element.transpose(interval)?,
1534                ))
1535            })
1536            .collect::<Result<Vec<_>>>()?;
1537        let mut out = Self::with_kind(self.kind);
1538        out.labels = self.labels.clone();
1539        out.events = events;
1540        out.sort_events();
1541        Ok(out)
1542    }
1543
1544    fn sort_events(&mut self) {
1545        self.events.sort_by(|left, right| {
1546            left.offset
1547                .partial_cmp(&right.offset)
1548                .unwrap_or(std::cmp::Ordering::Equal)
1549        });
1550    }
1551}
1552
1553/// Whether an element is a grace note or chord, which takes no time.
1554fn is_grace(element: &StreamElement) -> bool {
1555    element.duration().is_some_and(Duration::is_grace)
1556}
1557
1558/// How many leaves an element is: those of a nested stream, or itself.
1559fn leaf_count(element: &StreamElement) -> usize {
1560    match element {
1561        StreamElement::Stream(inner) => inner.leaves().len(),
1562        _ => 1,
1563    }
1564}
1565
1566impl<'a> IntoIterator for &'a Stream {
1567    type Item = &'a StreamEvent;
1568    type IntoIter = std::slice::Iter<'a, StreamEvent>;
1569
1570    fn into_iter(self) -> Self::IntoIter {
1571        self.events.iter()
1572    }
1573}
1574
1575#[cfg(test)]
1576mod tests {
1577    #[test]
1578    fn a_stream_has_part_like_streams_as_music21_decides() {
1579        use super::{Stream, StreamKind};
1580        use crate::note::Note;
1581
1582        // music21's own examples: a part, a measure, one generic stream at
1583        // the start, and a second one appended after it.
1584        let four_notes = |kind: StreamKind| {
1585            let mut stream = Stream::with_kind(kind);
1586            for _ in 0..4 {
1587                stream.push(Note::from_name("C4").unwrap());
1588            }
1589            stream
1590        };
1591        let mut score = Stream::with_kind(StreamKind::Score);
1592        assert!(!score.has_part_like_streams());
1593        score.insert(0.0, four_notes(StreamKind::Part));
1594        assert!(score.has_part_like_streams());
1595
1596        let mut score = Stream::with_kind(StreamKind::Score);
1597        score.push(four_notes(StreamKind::Measure));
1598        assert!(!score.has_part_like_streams());
1599
1600        let mut score = Stream::with_kind(StreamKind::Score);
1601        score.push(four_notes(StreamKind::Stream));
1602        assert!(score.has_part_like_streams());
1603        score.push(four_notes(StreamKind::Stream));
1604        assert!(!score.has_part_like_streams());
1605    }
1606
1607    #[test]
1608    fn a_stream_says_what_kind_it_is_and_walks_its_events() {
1609        use super::{Stream, StreamElement, StreamEvent, StreamKind};
1610        use crate::note::Note;
1611        use crate::pitch::Pitch;
1612        use crate::tempo::MetronomeMark;
1613
1614        assert_eq!(StreamKind::Voice.as_str(), "Voice");
1615        assert_eq!(StreamKind::Voice.to_string(), "Voice");
1616        let mut stream = Stream::new();
1617        assert!(stream.is_empty());
1618        stream.set_kind(StreamKind::Voice);
1619        assert_eq!(stream.kind(), StreamKind::Voice);
1620        assert!(matches!(
1621            StreamElement::from(MetronomeMark::new(120.0)),
1622            StreamElement::MetronomeMark(_)
1623        ));
1624
1625        let note = Note::from_pitch(Pitch::from_name("C4").unwrap());
1626        let rebuilt = Stream::from_events([StreamEvent::new(0.0, note)]);
1627        assert_eq!(rebuilt.iter().count(), 1);
1628        assert!(!rebuilt.is_empty());
1629        assert!(rebuilt.voices().is_empty());
1630        let mut outer = Stream::new();
1631        outer.push(stream);
1632        assert_eq!(outer.voices().len(), 1);
1633    }
1634
1635    use super::*;
1636
1637    #[test]
1638    fn a_stream_iterates_by_reference() {
1639        let mut stream = Stream::new();
1640        stream.push(Note::from_name("C4").unwrap());
1641        stream.push(Note::from_name("E4").unwrap());
1642
1643        let offsets: Vec<FloatType> = (&stream).into_iter().map(StreamEvent::offset).collect();
1644        assert_eq!(offsets, vec![0.0, 1.0]);
1645        assert_eq!((&stream).into_iter().count(), stream.len());
1646    }
1647
1648    #[test]
1649    fn stream_push_uses_durations() {
1650        let mut stream = Stream::new();
1651        stream.push(
1652            Note::from_name("C4")
1653                .unwrap()
1654                .with_duration(Duration::half()),
1655        );
1656        stream.push(Rest::from_quarter_length(0.5).unwrap());
1657        assert_eq!(stream.events()[0].offset(), 0.0);
1658        assert_eq!(stream.events()[1].offset(), 2.0);
1659        assert_eq!(stream.end_offset(), 2.5);
1660    }
1661
1662    #[test]
1663    fn stream_transposes_notes_and_chords() {
1664        let mut stream = Stream::new();
1665        stream.push(Note::from_name("C4").unwrap());
1666        stream.push(Chord::new("E4 G4").unwrap());
1667        let out = stream
1668            .transpose(&Interval::from_name("M2").unwrap())
1669            .unwrap();
1670        let names = out
1671            .pitches()
1672            .iter()
1673            .map(Pitch::name_with_octave)
1674            .collect::<Vec<_>>();
1675        assert_eq!(names, vec!["D4", "F#4", "A4"]);
1676    }
1677
1678    /// A score of one part of two measures, which is the shape music21 puts
1679    /// almost everything in.
1680    fn two_measure_score() -> Stream {
1681        let mut first = Stream::with_kind(StreamKind::Measure);
1682        first.insert(0.0, KeySignature::new(2));
1683        first.insert(0.0, TimeSignature::new(4, 4).unwrap());
1684        first.push(Note::from_name("D4").unwrap());
1685        first.push(Note::from_name("E4").unwrap());
1686        first.push(Note::from_name("F#4").unwrap());
1687        first.push(Note::from_name("G4").unwrap());
1688
1689        let mut second = Stream::with_kind(StreamKind::Measure);
1690        second.insert(0.0, KeySignature::new(-1));
1691        second.push(Note::from_name("A4").unwrap());
1692        second.push(Note::from_name("Bb4").unwrap());
1693
1694        let mut part = Stream::with_kind(StreamKind::Part);
1695        part.push(first);
1696        part.push(second);
1697
1698        let mut score = Stream::with_kind(StreamKind::Score);
1699        score.push(part);
1700        score
1701    }
1702
1703    #[test]
1704    fn a_nested_stream_flattens_onto_one_timeline() {
1705        let score = two_measure_score();
1706        assert_eq!(score.kind(), StreamKind::Score);
1707        assert_eq!(score.len(), 1, "a score holds its one part, not its notes");
1708        assert_eq!(score.parts().len(), 1);
1709        assert_eq!(score.parts()[0].measures().len(), 2);
1710
1711        // the second measure starts a bar in, so its notes do too
1712        let notes = score.notes();
1713        let offsets: Vec<FloatType> = notes.iter().map(|(offset, _)| *offset).collect();
1714        assert_eq!(offsets, vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
1715        assert_eq!(score.end_offset(), 6.0);
1716
1717        let names: Vec<String> = score
1718            .pitches()
1719            .iter()
1720            .map(Pitch::name_with_octave)
1721            .collect();
1722        assert_eq!(names, ["D4", "E4", "F#4", "G4", "A4", "Bb4"]);
1723
1724        // recurse sees the streams themselves; flatten does not
1725        assert_eq!(score.recurse().len(), 1 + 2 + 6 + 3);
1726        assert_eq!(score.flatten().len(), 6 + 3);
1727    }
1728
1729    #[test]
1730    fn the_key_in_force_is_the_last_one_written_before_it() {
1731        let score = two_measure_score();
1732        assert_eq!(score.key_signature_at(0.0).unwrap().sharps(), Some(2));
1733        assert_eq!(score.key_signature_at(3.5).unwrap().sharps(), Some(2));
1734        // the second measure changes it
1735        assert_eq!(score.key_signature_at(4.0).unwrap().sharps(), Some(-1));
1736        assert_eq!(score.key_signature_at(100.0).unwrap().sharps(), Some(-1));
1737        assert_eq!(
1738            score.time_signature_at(5.0).unwrap().ratio_string(),
1739            "4/4",
1740            "a metre stays in force across the bar that follows it"
1741        );
1742        assert!(score.metronome_mark_at(0.0).is_none());
1743
1744        // nothing is in force before the first mark
1745        let mut late = Stream::new();
1746        late.insert(2.0, KeySignature::new(3));
1747        assert!(late.key_signature_at(1.0).is_none());
1748        assert_eq!(late.key_signature_at(2.0).unwrap().sharps(), Some(3));
1749    }
1750
1751    #[test]
1752    fn transposing_a_score_moves_its_key_signatures_too() {
1753        let score = two_measure_score();
1754        let up = score
1755            .transpose(&Interval::from_name("M2").unwrap())
1756            .unwrap();
1757        assert_eq!(up.key_signature_at(0.0).unwrap().sharps(), Some(4));
1758        assert_eq!(up.key_signature_at(4.0).unwrap().sharps(), Some(1));
1759        let names: Vec<String> = up.pitches().iter().map(Pitch::name_with_octave).collect();
1760        assert_eq!(names, ["E4", "F#4", "G#4", "A4", "B4", "C5"]);
1761        assert_eq!(up.kind(), StreamKind::Score);
1762    }
1763}