Skip to main content

music21_rs/
expressions.rs

1//! Ornaments: the part of music21's `expressions` module that changes what
2//! is played.
3//!
4//! A mordent, a trill, a turn, an appoggiatura or a tremolo is written as one
5//! note and played as several. Each ornament here knows the note it
6//! decorates only through the pitch and the key signature it is given: from
7//! those it works out its ornamental pitches -- the neighbour a step above or
8//! below, spelled by the key unless the ornament carries an accidental of
9//! its own -- and realizes the note as the notes actually played.
10
11use crate::defaults::{FloatType, IntegerType};
12use crate::duration::Duration;
13use crate::error::{Error, Result};
14use crate::interval::{GenericInterval, Interval, IntervalDirection};
15use crate::key::keysignature::KeySignature;
16use crate::notation::{Tie, TieType};
17use crate::note::Note;
18use crate::pitch::{Accidental, AccidentalDisplayOptions, Pitch};
19use crate::spanner::{Spanner, SpannerKind};
20use crate::stream::{Stream, StreamElement};
21
22/// Which ornament a class is, as far as how it is played goes.
23#[derive(Clone, Copy, Debug, PartialEq, Eq)]
24enum Family {
25    /// Nothing to play: the base class and the schleifer.
26    Plain,
27    Mordent,
28    Trill,
29    Turn,
30    Appoggiatura,
31    Tremolo,
32}
33
34/// One of music21's ornament classes.
35#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
36#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
37pub enum OrnamentKind {
38    /// The base class, which plays the note as written.
39    Ornament,
40    /// An appoggiatura that has not said which way it resolves.
41    GeneralAppoggiatura,
42    /// A mordent that has not said which way it goes.
43    GeneralMordent,
44    /// A slide of two notes into the main one.
45    Schleifer,
46    /// Rapid repetitions of the note.
47    Tremolo,
48    /// A trill to the note above.
49    Trill,
50    /// The note above, the note, the note below, the note.
51    Turn,
52    /// A note a step above, resolving down.
53    Appoggiatura,
54    /// A trill a half step up.
55    HalfStepTrill,
56    /// A note a step below, resolving up.
57    InvertedAppoggiatura,
58    /// The note and the note above.
59    InvertedMordent,
60    /// A trill to the note below.
61    InvertedTrill,
62    /// The note below, the note, the note above, the note.
63    InvertedTurn,
64    /// The note and the note below.
65    Mordent,
66    /// A trill in shorter notes.
67    Shake,
68    /// A trill a whole step up.
69    WholeStepTrill,
70    /// An appoggiatura a half step above.
71    HalfStepAppoggiatura,
72    /// An appoggiatura a half step below.
73    HalfStepInvertedAppoggiatura,
74    /// An inverted mordent a half step up.
75    HalfStepInvertedMordent,
76    /// A mordent a half step down.
77    HalfStepMordent,
78    /// An appoggiatura a whole step above.
79    WholeStepAppoggiatura,
80    /// An appoggiatura a whole step below.
81    WholeStepInvertedAppoggiatura,
82    /// An inverted mordent a whole step up.
83    WholeStepInvertedMordent,
84    /// A mordent a whole step down.
85    WholeStepMordent,
86}
87
88/// What an ornament of one kind starts out as.
89struct KindRow {
90    kind: OrnamentKind,
91    class: &'static str,
92    /// Its ancestors up to `Ornament`, nearest first.
93    parents: &'static [&'static str],
94    family: Family,
95    /// Whether the ornamental note is above: `Some(true)` up, `Some(false)`
96    /// down, `None` for a general class that has not said.
97    up: Option<bool>,
98    /// The interval a half-step or whole-step ornament always uses, or an
99    /// appoggiatura's starting size.
100    fixed_size: Option<&'static str>,
101    quarter_length: FloatType,
102    placement: Option<&'static str>,
103    tie_attach: &'static str,
104}
105
106const KINDS: [KindRow; 24] = [
107    row(
108        OrnamentKind::Ornament,
109        "Ornament",
110        &[],
111        Family::Plain,
112        None,
113        None,
114        0.0,
115        None,
116        "first",
117    ),
118    row(
119        OrnamentKind::GeneralAppoggiatura,
120        "GeneralAppoggiatura",
121        &["Ornament"],
122        Family::Appoggiatura,
123        None,
124        Some("M2"),
125        0.0,
126        None,
127        "first",
128    ),
129    row(
130        OrnamentKind::GeneralMordent,
131        "GeneralMordent",
132        &["Ornament"],
133        Family::Mordent,
134        None,
135        None,
136        0.125,
137        Some("above"),
138        "first",
139    ),
140    row(
141        OrnamentKind::Schleifer,
142        "Schleifer",
143        &["Ornament"],
144        Family::Plain,
145        None,
146        None,
147        0.25,
148        None,
149        "first",
150    ),
151    row(
152        OrnamentKind::Tremolo,
153        "Tremolo",
154        &["Ornament"],
155        Family::Tremolo,
156        None,
157        None,
158        0.0,
159        None,
160        "first",
161    ),
162    row(
163        OrnamentKind::Trill,
164        "Trill",
165        &["Ornament"],
166        Family::Trill,
167        Some(true),
168        None,
169        0.125,
170        Some("above"),
171        "all",
172    ),
173    row(
174        OrnamentKind::Turn,
175        "Turn",
176        &["Ornament"],
177        Family::Turn,
178        None,
179        None,
180        0.25,
181        Some("above"),
182        "all",
183    ),
184    row(
185        OrnamentKind::Appoggiatura,
186        "Appoggiatura",
187        &["GeneralAppoggiatura", "Ornament"],
188        Family::Appoggiatura,
189        Some(false),
190        Some("M2"),
191        0.0,
192        None,
193        "first",
194    ),
195    row(
196        OrnamentKind::HalfStepTrill,
197        "HalfStepTrill",
198        &["Trill", "Ornament"],
199        Family::Trill,
200        Some(true),
201        Some("m2"),
202        0.125,
203        Some("above"),
204        "all",
205    ),
206    row(
207        OrnamentKind::InvertedAppoggiatura,
208        "InvertedAppoggiatura",
209        &["GeneralAppoggiatura", "Ornament"],
210        Family::Appoggiatura,
211        Some(true),
212        Some("M2"),
213        0.0,
214        None,
215        "first",
216    ),
217    row(
218        OrnamentKind::InvertedMordent,
219        "InvertedMordent",
220        &["GeneralMordent", "Ornament"],
221        Family::Mordent,
222        Some(true),
223        None,
224        0.125,
225        Some("above"),
226        "first",
227    ),
228    row(
229        OrnamentKind::InvertedTrill,
230        "InvertedTrill",
231        &["Trill", "Ornament"],
232        Family::Trill,
233        Some(false),
234        None,
235        0.125,
236        Some("above"),
237        "all",
238    ),
239    row(
240        OrnamentKind::InvertedTurn,
241        "InvertedTurn",
242        &["Turn", "Ornament"],
243        Family::Turn,
244        None,
245        None,
246        0.25,
247        Some("above"),
248        "all",
249    ),
250    row(
251        OrnamentKind::Mordent,
252        "Mordent",
253        &["GeneralMordent", "Ornament"],
254        Family::Mordent,
255        Some(false),
256        None,
257        0.125,
258        Some("above"),
259        "first",
260    ),
261    row(
262        OrnamentKind::Shake,
263        "Shake",
264        &["Trill", "Ornament"],
265        Family::Trill,
266        Some(true),
267        None,
268        0.25,
269        Some("above"),
270        "all",
271    ),
272    row(
273        OrnamentKind::WholeStepTrill,
274        "WholeStepTrill",
275        &["Trill", "Ornament"],
276        Family::Trill,
277        Some(true),
278        Some("M2"),
279        0.125,
280        Some("above"),
281        "all",
282    ),
283    row(
284        OrnamentKind::HalfStepAppoggiatura,
285        "HalfStepAppoggiatura",
286        &["Appoggiatura", "GeneralAppoggiatura", "Ornament"],
287        Family::Appoggiatura,
288        Some(false),
289        Some("m2"),
290        0.0,
291        None,
292        "first",
293    ),
294    row(
295        OrnamentKind::HalfStepInvertedAppoggiatura,
296        "HalfStepInvertedAppoggiatura",
297        &["InvertedAppoggiatura", "GeneralAppoggiatura", "Ornament"],
298        Family::Appoggiatura,
299        Some(true),
300        Some("m2"),
301        0.0,
302        None,
303        "first",
304    ),
305    row(
306        OrnamentKind::HalfStepInvertedMordent,
307        "HalfStepInvertedMordent",
308        &["InvertedMordent", "GeneralMordent", "Ornament"],
309        Family::Mordent,
310        Some(true),
311        Some("m2"),
312        0.125,
313        Some("above"),
314        "first",
315    ),
316    row(
317        OrnamentKind::HalfStepMordent,
318        "HalfStepMordent",
319        &["Mordent", "GeneralMordent", "Ornament"],
320        Family::Mordent,
321        Some(false),
322        Some("m-2"),
323        0.125,
324        Some("above"),
325        "first",
326    ),
327    row(
328        OrnamentKind::WholeStepAppoggiatura,
329        "WholeStepAppoggiatura",
330        &["Appoggiatura", "GeneralAppoggiatura", "Ornament"],
331        Family::Appoggiatura,
332        Some(false),
333        Some("M2"),
334        0.0,
335        None,
336        "first",
337    ),
338    row(
339        OrnamentKind::WholeStepInvertedAppoggiatura,
340        "WholeStepInvertedAppoggiatura",
341        &["InvertedAppoggiatura", "GeneralAppoggiatura", "Ornament"],
342        Family::Appoggiatura,
343        Some(true),
344        Some("M2"),
345        0.0,
346        None,
347        "first",
348    ),
349    row(
350        OrnamentKind::WholeStepInvertedMordent,
351        "WholeStepInvertedMordent",
352        &["InvertedMordent", "GeneralMordent", "Ornament"],
353        Family::Mordent,
354        Some(true),
355        Some("M2"),
356        0.125,
357        Some("above"),
358        "first",
359    ),
360    row(
361        OrnamentKind::WholeStepMordent,
362        "WholeStepMordent",
363        &["Mordent", "GeneralMordent", "Ornament"],
364        Family::Mordent,
365        Some(false),
366        Some("M-2"),
367        0.125,
368        Some("above"),
369        "first",
370    ),
371];
372
373#[allow(clippy::too_many_arguments)]
374const fn row(
375    kind: OrnamentKind,
376    class: &'static str,
377    parents: &'static [&'static str],
378    family: Family,
379    up: Option<bool>,
380    fixed_size: Option<&'static str>,
381    quarter_length: FloatType,
382    placement: Option<&'static str>,
383    tie_attach: &'static str,
384) -> KindRow {
385    KindRow {
386        kind,
387        class,
388        parents,
389        family,
390        up,
391        fixed_size,
392        quarter_length,
393        placement,
394        tie_attach,
395    }
396}
397
398impl OrnamentKind {
399    /// Every kind, parents before children.
400    pub const ALL: [OrnamentKind; 24] = [
401        OrnamentKind::Ornament,
402        OrnamentKind::GeneralAppoggiatura,
403        OrnamentKind::GeneralMordent,
404        OrnamentKind::Schleifer,
405        OrnamentKind::Tremolo,
406        OrnamentKind::Trill,
407        OrnamentKind::Turn,
408        OrnamentKind::Appoggiatura,
409        OrnamentKind::HalfStepTrill,
410        OrnamentKind::InvertedAppoggiatura,
411        OrnamentKind::InvertedMordent,
412        OrnamentKind::InvertedTrill,
413        OrnamentKind::InvertedTurn,
414        OrnamentKind::Mordent,
415        OrnamentKind::Shake,
416        OrnamentKind::WholeStepTrill,
417        OrnamentKind::HalfStepAppoggiatura,
418        OrnamentKind::HalfStepInvertedAppoggiatura,
419        OrnamentKind::HalfStepInvertedMordent,
420        OrnamentKind::HalfStepMordent,
421        OrnamentKind::WholeStepAppoggiatura,
422        OrnamentKind::WholeStepInvertedAppoggiatura,
423        OrnamentKind::WholeStepInvertedMordent,
424        OrnamentKind::WholeStepMordent,
425    ];
426
427    fn row(self) -> &'static KindRow {
428        KINDS
429            .iter()
430            .find(|row| row.kind == self)
431            .expect("every kind has a row")
432    }
433
434    /// music21's class name for the kind: `"InvertedMordent"`.
435    pub fn class_name(self) -> &'static str {
436        self.row().class
437    }
438
439    /// The kind music21 names by that class.
440    pub fn from_class_name(class: &str) -> Option<Self> {
441        KINDS
442            .iter()
443            .find(|row| row.class == class)
444            .map(|row| row.kind)
445    }
446
447    /// The classes above this one, nearest first, up to `Ornament`.
448    pub fn parents(self) -> &'static [&'static str] {
449        self.row().parents
450    }
451
452    /// Whether the kind always uses one interval, as the half-step and
453    /// whole-step mordents and trills do, and so takes no accidental.
454    pub fn has_fixed_size(self) -> bool {
455        self.row().fixed_size.is_some()
456            && matches!(self.row().family, Family::Mordent | Family::Trill)
457    }
458}
459
460/// When a turn starts: music21's `OrnamentDelay`.
461#[derive(Clone, Copy, Debug, PartialEq)]
462#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
463pub enum OrnamentDelay {
464    /// At once, on the beat.
465    NoDelay,
466    /// Halfway through the note.
467    Default,
468    /// After so many quarter lengths.
469    Timed(FloatType),
470}
471
472/// Which neighbour of a turn.
473#[derive(Clone, Copy, Debug, PartialEq, Eq)]
474pub enum TurnNote {
475    /// The note above.
476    Upper,
477    /// The note below.
478    Lower,
479}
480
481/// A note realized as an ornament plays it: the notes before what is left of
482/// it, what is left (nothing where the ornament takes the whole note, as a
483/// trill does), and the notes after.
484#[derive(Clone, Debug)]
485pub struct Realization {
486    /// The notes played before the main note.
487    pub before: Vec<Note>,
488    /// What is left of the main note.
489    pub main: Option<Note>,
490    /// The notes played after it.
491    pub after: Vec<Note>,
492}
493
494impl Realization {
495    /// Every note in the order played.
496    pub fn into_notes(self) -> Vec<Note> {
497        let mut notes = self.before;
498        notes.extend(self.main);
499        notes.extend(self.after);
500        notes
501    }
502}
503
504/// An ornament.
505///
506/// ```
507/// use music21_rs::expressions::{Ornament, OrnamentKind};
508/// use music21_rs::{KeySignature, Note};
509///
510/// let mordent = Ornament::of_kind(OrnamentKind::Mordent);
511/// let played = mordent.realize(&Note::from_name("C4")?, &KeySignature::new(0))?;
512/// let names: Vec<String> = played
513///     .into_notes()
514///     .iter()
515///     .map(|note| {
516///         let length = note.duration().map_or(1.0, |duration| duration.quarter_length());
517///         format!("{} {length}", note.pitch().name_with_octave())
518///     })
519///     .collect();
520/// assert_eq!(names, ["C4 0.125", "B3 0.125", "C4 0.75"]);
521/// # Ok::<(), music21_rs::Error>(())
522/// ```
523#[derive(Clone, Debug, PartialEq)]
524#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
525#[must_use]
526pub struct Ornament {
527    kind: OrnamentKind,
528    quarter_length: FloatType,
529    auto_scale: bool,
530    placement: Option<String>,
531    tie_attach: String,
532    accidental: Option<Accidental>,
533    upper_accidental: Option<Accidental>,
534    lower_accidental: Option<Accidental>,
535    delay: OrnamentDelay,
536    nachschlag: bool,
537    number_of_marks: u8,
538    measured: bool,
539    size: Option<Interval>,
540}
541
542impl Default for Ornament {
543    /// music21's bare `Ornament`.
544    fn default() -> Self {
545        Self::of_kind(OrnamentKind::Ornament)
546    }
547}
548
549impl Ornament {
550    /// An ornament as music21's class for `kind` starts out.
551    pub fn of_kind(kind: OrnamentKind) -> Self {
552        let row = kind.row();
553        let size = match row.family {
554            Family::Appoggiatura => row
555                .fixed_size
556                .map(|name| Interval::from_name(name).expect("a fixed interval name")),
557            _ => None,
558        };
559        Self {
560            kind,
561            quarter_length: row.quarter_length,
562            auto_scale: true,
563            placement: row.placement.map(str::to_string),
564            tie_attach: row.tie_attach.to_string(),
565            accidental: None,
566            upper_accidental: None,
567            lower_accidental: None,
568            delay: OrnamentDelay::NoDelay,
569            nachschlag: false,
570            number_of_marks: 3,
571            measured: true,
572            size,
573        }
574    }
575
576    /// The kind of ornament this started as.
577    pub fn kind(&self) -> OrnamentKind {
578        self.kind
579    }
580
581    /// Whether this is an ornament of that music21 class or one below it.
582    pub fn is_a(&self, class: &str) -> bool {
583        self.kind.class_name() == class || self.kind.parents().contains(&class)
584    }
585
586    fn family(&self) -> Family {
587        self.kind.row().family
588    }
589
590    /// Which way a mordent, trill or appoggiatura goes to its ornamental
591    /// note: music21's `direction`. Nothing for a general mordent or
592    /// appoggiatura that has not said, and for an ornament of another kind.
593    pub fn direction(&self) -> Option<IntervalDirection> {
594        match self.family() {
595            Family::Mordent | Family::Trill | Family::Appoggiatura => {
596                self.kind.row().up.map(|up| {
597                    if up {
598                        IntervalDirection::Ascending
599                    } else {
600                        IntervalDirection::Descending
601                    }
602                })
603            }
604            _ => None,
605        }
606    }
607
608    /// music21's `name`: the class as lower-case words, with a mordent's or
609    /// trill's accidental, and a turn's delay and accidentals, beside it.
610    pub fn name(&self) -> String {
611        let mut name =
612            crate::common::stringtools::camel_case_to_hyphen(self.kind.class_name(), ' ');
613        match self.family() {
614            Family::Mordent | Family::Trill => {
615                if let Some(accidental) = &self.accidental {
616                    name = format!("{name} ({})", accidental.name());
617                }
618            }
619            Family::Turn => {
620                match self.delay {
621                    OrnamentDelay::Default => name = format!("delayed {name}"),
622                    OrnamentDelay::Timed(delay) => {
623                        name = format!("delayed(delayQL={}) {name}", python_float(delay));
624                    }
625                    OrnamentDelay::NoDelay => {}
626                }
627                let parts: Vec<String> = [
628                    self.upper_accidental
629                        .as_ref()
630                        .map(|accidental| format!("upper={}", accidental.name())),
631                    self.lower_accidental
632                        .as_ref()
633                        .map(|accidental| format!("lower={}", accidental.name())),
634                ]
635                .into_iter()
636                .flatten()
637                .collect();
638                if !parts.is_empty() {
639                    name = format!("{name} ({})", parts.join(", "));
640                }
641            }
642            _ => {}
643        }
644        name
645    }
646
647    /// How long each ornamental note lasts, in quarter lengths: music21's
648    /// `quarterLength`.
649    pub fn quarter_length(&self) -> FloatType {
650        self.quarter_length
651    }
652
653    /// Changes how long each ornamental note lasts.
654    pub fn set_quarter_length(&mut self, quarter_length: FloatType) {
655        self.quarter_length = quarter_length;
656    }
657
658    /// Whether the ornament shrinks to fit a note too short for it: music21's
659    /// `autoScale`.
660    pub fn auto_scale(&self) -> bool {
661        self.auto_scale
662    }
663
664    /// Says whether the ornament shrinks to fit.
665    pub fn set_auto_scale(&mut self, auto_scale: bool) {
666        self.auto_scale = auto_scale;
667    }
668
669    /// Where the sign sits.
670    pub fn placement(&self) -> Option<&str> {
671        self.placement.as_deref()
672    }
673
674    /// Says where the sign sits.
675    pub fn set_placement(&mut self, placement: Option<String>) {
676        self.placement = placement;
677    }
678
679    /// Which part of a note split across a tie keeps the ornament.
680    pub fn tie_attach(&self) -> &str {
681        &self.tie_attach
682    }
683
684    /// Changes which part keeps it.
685    pub fn set_tie_attach(&mut self, attach: impl Into<String>) {
686        self.tie_attach = attach.into();
687    }
688
689    /// Carries this trill onto the pieces a trilled note was split into:
690    /// music21's `splitClient`, which its `splitAtQuarterLength` calls.
691    ///
692    /// The pieces are the leaves of `stream` at `positions`, first to last.
693    /// The trill is written on the first piece alone, and where there is
694    /// more than one piece they are joined by a trill extension, the spanner
695    /// answered, unless one of `stream`'s trill extensions already takes in
696    /// the first. The spanner is answered rather than added, as music21's is.
697    ///
698    /// ```
699    /// use music21_rs::{
700    ///     expressions::{Ornament, OrnamentKind},
701    ///     Duration, Note, SpannerKind, Stream,
702    /// };
703    ///
704    /// let mut stream = Stream::new();
705    /// stream.insert(0.0, Note::from_name("C4")?.with_duration(Duration::new(3.0)?));
706    /// stream.insert(3.0, Note::from_name("C4")?);
707    /// let trill = Ornament::of_kind(OrnamentKind::Trill);
708    /// let extension = trill.split_client(&mut stream, &[0, 1])?.unwrap();
709    /// assert_eq!(extension.kind(), SpannerKind::TrillExtension);
710    /// assert_eq!(extension.spanned(), [Some(0), Some(1)]);
711    /// # Ok::<(), music21_rs::Error>(())
712    /// ```
713    ///
714    /// # Errors
715    ///
716    /// An ornament that is not a trill, which music21 gives no such hook, or
717    /// a first piece that is not a note, a chord or a rest.
718    pub fn split_client(
719        &self,
720        stream: &mut Stream,
721        positions: &[usize],
722    ) -> Result<Option<Spanner>> {
723        if !self.is_a("Trill") {
724            return Err(Error::Expression(format!(
725                "a {} is not split with the note it is on; only a trill is",
726                self.kind.class_name()
727            )));
728        }
729        let Some(&first) = positions.first() else {
730            return Ok(None);
731        };
732        let mut position = 0;
733        let mut placed = false;
734        stream.for_each_mut(&mut |_, element| {
735            if position == first {
736                let expressions = match element {
737                    StreamElement::Note(note) => Some(note.expressions_mut()),
738                    StreamElement::Chord(chord) => Some(chord.expressions_mut()),
739                    StreamElement::Rest(rest) => Some(rest.expressions_mut()),
740                    StreamElement::Unpitched(stroke) => {
741                        Some(stroke.written_mut().expressions_mut())
742                    }
743                    _ => None,
744                };
745                if let Some(expressions) = expressions {
746                    expressions.push(Expression::from(self.clone()));
747                    placed = true;
748                }
749            }
750            position += 1;
751        });
752        if !placed {
753            return Err(Error::Expression(format!(
754                "there is no note at position {first} to carry the trill"
755            )));
756        }
757        let extended = stream.spanners().iter().any(|spanner| {
758            spanner.kind() == SpannerKind::TrillExtension
759                && spanner.spanned().contains(&Some(first))
760        });
761        if positions.len() > 1 && !extended {
762            return Ok(Some(Spanner::new(
763                SpannerKind::TrillExtension,
764                positions.to_vec(),
765            )));
766        }
767        Ok(None)
768    }
769
770    /// A mordent's or trill's accidental, which spells its ornamental note
771    /// instead of the key signature.
772    pub fn accidental(&self) -> Option<&Accidental> {
773        self.accidental.as_ref()
774    }
775
776    /// Changes the accidental.
777    ///
778    /// # Errors
779    ///
780    /// A half-step or whole-step ornament, whose interval is fixed.
781    pub fn set_accidental(&mut self, accidental: Option<Accidental>) -> Result<()> {
782        if self.kind.has_fixed_size() {
783            return Err(Error::Expression(format!(
784                "Cannot set accidental of {}",
785                self.kind.class_name()
786            )));
787        }
788        self.accidental = accidental;
789        Ok(())
790    }
791
792    /// A turn's accidental for its upper note.
793    pub fn upper_accidental(&self) -> Option<&Accidental> {
794        self.upper_accidental.as_ref()
795    }
796
797    /// Changes a turn's upper accidental.
798    pub fn set_upper_accidental(&mut self, accidental: Option<Accidental>) {
799        self.upper_accidental = accidental;
800    }
801
802    /// A turn's accidental for its lower note.
803    pub fn lower_accidental(&self) -> Option<&Accidental> {
804        self.lower_accidental.as_ref()
805    }
806
807    /// Changes a turn's lower accidental.
808    pub fn set_lower_accidental(&mut self, accidental: Option<Accidental>) {
809        self.lower_accidental = accidental;
810    }
811
812    /// When a turn starts.
813    pub fn delay(&self) -> OrnamentDelay {
814        self.delay
815    }
816
817    /// Changes when a turn starts; a timed delay of nothing is no delay.
818    pub fn set_delay(&mut self, delay: OrnamentDelay) {
819        self.delay = match delay {
820            OrnamentDelay::Timed(length) if length <= 0.0 => OrnamentDelay::NoDelay,
821            other => other,
822        };
823    }
824
825    /// Whether a turn waits before starting.
826    pub fn is_delayed(&self) -> bool {
827        self.delay != OrnamentDelay::NoDelay
828    }
829
830    /// Whether a trill ends on two notes turning back into the next:
831    /// music21's `nachschlag`.
832    pub fn nachschlag(&self) -> bool {
833        self.nachschlag
834    }
835
836    /// Says whether a trill ends on a nachschlag.
837    pub fn set_nachschlag(&mut self, nachschlag: bool) {
838        self.nachschlag = nachschlag;
839    }
840
841    /// How many strokes cross a tremolo's stem, nought to eight.
842    pub fn number_of_marks(&self) -> u8 {
843        self.number_of_marks
844    }
845
846    /// Changes how many strokes cross the stem.
847    ///
848    /// # Errors
849    ///
850    /// More than eight.
851    pub fn set_number_of_marks(&mut self, marks: u8) -> Result<()> {
852        if marks > 8 {
853            return Err(Error::Expression(
854                "Number of marks must be a number from 0 to 8".to_string(),
855            ));
856        }
857        self.number_of_marks = marks;
858        Ok(())
859    }
860
861    /// Whether a tremolo is measured.
862    pub fn measured(&self) -> bool {
863        self.measured
864    }
865
866    /// Says whether a tremolo is measured.
867    pub fn set_measured(&mut self, measured: bool) {
868        self.measured = measured;
869    }
870
871    /// An appoggiatura's size: how far from the main note its first note is.
872    pub fn appoggiatura_size(&self) -> Option<&Interval> {
873        self.size.as_ref()
874    }
875
876    /// Changes an appoggiatura's size.
877    pub fn set_appoggiatura_size(&mut self, size: Option<Interval>) {
878        self.size = size;
879    }
880
881    /// The interval from `source` to a mordent's or trill's ornamental note,
882    /// under `key`: music21's `getSize`.
883    ///
884    /// ```
885    /// use music21_rs::expressions::{Ornament, OrnamentKind};
886    /// use music21_rs::{KeySignature, Pitch};
887    ///
888    /// let mordent = Ornament::of_kind(OrnamentKind::Mordent);
889    /// let g = Pitch::from_name("G4")?;
890    /// assert_eq!(mordent.size(&g, &KeySignature::new(0))?.directed_name(), "M-2");
891    /// assert_eq!(mordent.size(&g, &KeySignature::new(1))?.directed_name(), "m-2");
892    /// # Ok::<(), music21_rs::Error>(())
893    /// ```
894    ///
895    /// # Errors
896    ///
897    /// An ornament that is not a mordent or a trill, or a general mordent
898    /// that has not said which way it goes.
899    pub fn size(&self, source: &Pitch, key: &KeySignature) -> Result<Interval> {
900        let row = self.kind.row();
901        let what = match row.family {
902            Family::Mordent => "mordent",
903            Family::Trill => "trill",
904            _ => {
905                return Err(Error::Expression(format!(
906                    "a {} has no single size",
907                    self.name()
908                )));
909            }
910        };
911        if let Some(name) = row.fixed_size {
912            return Interval::from_name(name);
913        }
914        let Some(up) = row.up else {
915            return Err(Error::Expression(format!(
916                "Cannot compute {what} size if I do not know its direction"
917            )));
918        };
919        neighbour(source, up, self.accidental.as_ref(), key)
920    }
921
922    /// The interval from `source` to a turn's upper or lower note, under
923    /// `key`: music21's `Turn.getSize`.
924    ///
925    /// # Errors
926    ///
927    /// An ornament that is not a turn.
928    pub fn turn_size(
929        &self,
930        source: &Pitch,
931        which: TurnNote,
932        key: &KeySignature,
933    ) -> Result<Interval> {
934        if self.family() != Family::Turn {
935            return Err(Error::Expression(format!(
936                "a {} is not a turn",
937                self.name()
938            )));
939        }
940        match which {
941            TurnNote::Upper => neighbour(source, true, self.upper_accidental.as_ref(), key),
942            TurnNote::Lower => neighbour(source, false, self.lower_accidental.as_ref(), key),
943        }
944    }
945
946    /// The pitches the ornament plays besides `source` itself, under `key`:
947    /// music21's `resolveOrnamentalPitches` and `ornamentalPitches`. A
948    /// mordent or trill has one, a turn its upper and lower notes in that
949    /// order, and any other ornament none. An ornament's own accidental
950    /// passes its display status on to the pitch it spells.
951    ///
952    /// # Errors
953    ///
954    /// A general mordent that has not said which way it goes.
955    pub fn ornamental_pitches(&self, source: &Pitch, key: &KeySignature) -> Result<Vec<Pitch>> {
956        let resolved = |interval: &Interval, accidental: Option<&Accidental>| -> Result<Pitch> {
957            let mut from = source.clone();
958            from.set_octave_is_implicit(false);
959            let mut ornamental = from.transpose(interval)?;
960            if ornamental
961                .microtone()
962                .is_some_and(|microtone| microtone.cents() != 0.0)
963            {
964                ornamental = ornamental.convert_microtones_to_quarter_tones()?;
965            }
966            if let Some(accidental) = accidental {
967                let status = accidental.display_status();
968                let mut written = ornamental.accidental().clone();
969                written.set_display_status(status);
970                ornamental.set_accidental(written);
971            }
972            Ok(ornamental)
973        };
974        match self.family() {
975            Family::Mordent | Family::Trill => {
976                let interval = self.size(source, key)?;
977                Ok(vec![resolved(&interval, self.accidental.as_ref())?])
978            }
979            Family::Turn => {
980                let upper = self.turn_size(source, TurnNote::Upper, key)?;
981                let lower = self.turn_size(source, TurnNote::Lower, key)?;
982                Ok(vec![
983                    resolved(&upper, self.upper_accidental.as_ref())?,
984                    resolved(&lower, self.lower_accidental.as_ref())?,
985                ])
986            }
987            _ => Ok(Vec::new()),
988        }
989    }
990
991    /// Decides whether each of this ornament's ornamental pitches shows its
992    /// accidental: music21's `updateAccidentalDisplay` on an ornament.
993    ///
994    /// `ornamental` is what [`Ornament::ornamental_pitches`] gave, in its
995    /// order. An accidental the ornament was given with a display status of
996    /// its own says so outright, adding a natural where the pitch has no
997    /// accidental; otherwise each pitch is decided as
998    /// [`Pitch::update_accidental_display`] decides one, against `options`,
999    /// but never as simultaneous with anything and never tied, since an
1000    /// ornamental note is neither. An ornament with no ornamental pitches
1001    /// leaves them alone.
1002    pub fn update_accidental_display(
1003        &self,
1004        ornamental: &mut [Pitch],
1005        options: &AccidentalDisplayOptions<'_>,
1006    ) {
1007        let governing = match self.family() {
1008            Family::Mordent | Family::Trill => vec![self.accidental.as_ref()],
1009            Family::Turn => vec![
1010                self.upper_accidental.as_ref(),
1011                self.lower_accidental.as_ref(),
1012            ],
1013            _ => return,
1014        };
1015        let untied = AccidentalDisplayOptions {
1016            other_simultaneous_pitches: &[],
1017            last_note_was_tied: false,
1018            ..*options
1019        };
1020        for (pitch, accidental) in ornamental.iter_mut().zip(governing) {
1021            let says = accidental.filter(|accidental| accidental.display_status().is_some());
1022            match says {
1023                Some(accidental) => {
1024                    let mut shown = pitch.accidental().clone();
1025                    shown.set_display_status(accidental.display_status());
1026                    pitch.set_accidental(shown);
1027                }
1028                None => pitch.update_accidental_display(&untied),
1029            }
1030        }
1031    }
1032
1033    /// The notes `note` is played as under this ornament, in `key`:
1034    /// music21's `realize`.
1035    ///
1036    /// # Errors
1037    ///
1038    /// A note with no length to steal time from (a tremolo takes one as it
1039    /// is), a note too short for an ornament told not to shrink, or a general
1040    /// mordent or appoggiatura that has not said which way it goes.
1041    pub fn realize(&self, note: &Note, key: &KeySignature) -> Result<Realization> {
1042        // A note that says no length lasts a quarter, as music21's does.
1043        let length = note.duration().map_or(1.0, Duration::quarter_length);
1044        match self.family() {
1045            Family::Plain => Ok(Realization {
1046                before: Vec::new(),
1047                main: Some(note.clone()),
1048                after: Vec::new(),
1049            }),
1050            Family::Mordent => self.realize_mordent(note, key, length),
1051            Family::Trill => self.realize_trill(note, key, length),
1052            Family::Turn => self.realize_turn(note, key, length),
1053            Family::Appoggiatura => self.realize_appoggiatura(note, length),
1054            Family::Tremolo => self.realize_tremolo(note, length),
1055        }
1056    }
1057
1058    fn realize_mordent(
1059        &self,
1060        note: &Note,
1061        key: &KeySignature,
1062        length: FloatType,
1063    ) -> Result<Realization> {
1064        if self.kind.row().up.is_none() {
1065            return Err(Error::Expression(
1066                "Cannot realize a mordent if I do not know its direction".to_string(),
1067            ));
1068        }
1069        no_time_to_steal(length)?;
1070        let mut each = self.quarter_length;
1071        if length <= self.quarter_length * 2.0 {
1072            if !self.auto_scale {
1073                return Err(Error::Expression(
1074                    "The note is not long enough to realize a mordent".to_string(),
1075                ));
1076            }
1077            each = length / 4.0;
1078        }
1079        let interval = self.size(note.pitch(), key)?;
1080        let mut second = lasting(note, each)?;
1081        let mut moved = second.pitch().transpose(&interval)?;
1082        if moved.written_accidental().is_none() {
1083            moved.set_written_accidental(key.accidental_by_step(moved.step().as_char())?);
1084        }
1085        second.set_pitch(moved);
1086        Ok(Realization {
1087            before: vec![lasting(note, each)?, second],
1088            main: Some(lasting(note, length - 2.0 * each)?),
1089            after: Vec::new(),
1090        })
1091    }
1092
1093    fn realize_trill(
1094        &self,
1095        note: &Note,
1096        key: &KeySignature,
1097        length: FloatType,
1098    ) -> Result<Realization> {
1099        no_time_to_steal(length)?;
1100        let mut each = self.quarter_length;
1101        if length < 2.0 * each {
1102            if !self.auto_scale {
1103                return Err(Error::Expression(
1104                    "The note is not long enough to realize a trill".to_string(),
1105                ));
1106            }
1107            each = length / 2.0;
1108        }
1109        if length < 4.0 * self.quarter_length && self.nachschlag {
1110            if !self.auto_scale {
1111                return Err(Error::Expression(
1112                    "The note is not long enough for a nachschlag".to_string(),
1113                ));
1114            }
1115            each = length / 4.0;
1116        }
1117        let interval = self.size(note.pitch(), key)?;
1118        let from_key = !self.kind.has_fixed_size();
1119        let mut count = (length / each) as IntegerType;
1120        if self.nachschlag {
1121            count -= 2;
1122        }
1123        let written = note.pitch().name_with_octave();
1124        let mut trilled = Vec::new();
1125        for _ in 0..(count / 2) {
1126            trilled.push(lasting(note, each)?);
1127            let mut upper = lasting(note, each)?;
1128            upper.set_pitch(upper.pitch().transpose(&interval)?);
1129            trilled.push(upper);
1130        }
1131        if from_key {
1132            for played in &mut trilled {
1133                if played.pitch().name_with_octave() != written
1134                    && played.pitch().written_accidental().is_none()
1135                {
1136                    let mut pitch = played.pitch().clone();
1137                    pitch.set_written_accidental(key.accidental_by_step(pitch.step().as_char())?);
1138                    played.set_pitch(pitch);
1139                }
1140            }
1141        }
1142        if !self.nachschlag {
1143            return Ok(Realization {
1144                before: trilled,
1145                main: None,
1146                after: Vec::new(),
1147            });
1148        }
1149        let mut first = lasting(note, each)?;
1150        let mut second = lasting(note, each)?;
1151        second.set_pitch(second.pitch().transpose(&interval.reversed()?)?);
1152        if from_key {
1153            for played in [&mut first, &mut second] {
1154                let mut pitch = played.pitch().clone();
1155                pitch.set_written_accidental(key.accidental_by_step(pitch.step().as_char())?);
1156                played.set_pitch(pitch);
1157            }
1158        }
1159        Ok(Realization {
1160            before: trilled,
1161            main: None,
1162            after: vec![first, second],
1163        })
1164    }
1165
1166    fn realize_turn(
1167        &self,
1168        note: &Note,
1169        key: &KeySignature,
1170        length: FloatType,
1171    ) -> Result<Realization> {
1172        no_time_to_steal(length)?;
1173        let remainder = match self.delay {
1174            OrnamentDelay::NoDelay => 0.0,
1175            OrnamentDelay::Default => length / 2.0,
1176            OrnamentDelay::Timed(delay) => delay,
1177        };
1178        let turn_length = length - remainder;
1179        let mut each = self.quarter_length;
1180        let mut last = None;
1181        if turn_length < 4.0 * self.quarter_length {
1182            if !self.auto_scale {
1183                return Err(Error::Expression(
1184                    "The note is not long enough to realize a turn".to_string(),
1185                ));
1186            }
1187            each = turn_length / 4.0;
1188        } else if turn_length > 4.0 * self.quarter_length {
1189            last = Some(turn_length - 3.0 * each);
1190        }
1191        let inverted = self.kind == OrnamentKind::InvertedTurn;
1192        let (first_side, third_side) = if inverted {
1193            (TurnNote::Lower, TurnNote::Upper)
1194        } else {
1195            (TurnNote::Upper, TurnNote::Lower)
1196        };
1197        let first_interval = self.turn_size(note.pitch(), first_side, key)?;
1198        let third_interval = self.turn_size(note.pitch(), third_side, key)?;
1199        let mut first = lasting(note, each)?;
1200        first.set_pitch(first.pitch().transpose(&first_interval)?);
1201        let second = lasting(note, each)?;
1202        let mut third = lasting(note, each)?;
1203        third.set_pitch(third.pitch().transpose(&third_interval)?);
1204        let fourth = lasting(note, last.unwrap_or(each))?;
1205        let mut turned = vec![first, second, third, fourth];
1206        for index in [0, 2] {
1207            if turned[index].pitch().written_accidental().is_none() {
1208                let mut pitch = turned[index].pitch().clone();
1209                pitch.set_written_accidental(key.accidental_by_step(pitch.step().as_char())?);
1210                turned[index].set_pitch(pitch);
1211            }
1212        }
1213        if remainder == 0.0 {
1214            return Ok(Realization {
1215                before: Vec::new(),
1216                main: None,
1217                after: turned,
1218            });
1219        }
1220        Ok(Realization {
1221            before: Vec::new(),
1222            main: Some(lasting(note, remainder)?),
1223            after: turned,
1224        })
1225    }
1226
1227    fn realize_appoggiatura(&self, note: &Note, length: FloatType) -> Result<Realization> {
1228        let Some(up) = self.kind.row().up else {
1229            return Err(Error::Expression(
1230                "Cannot realize an Appoggiatura if I do not know its direction".to_string(),
1231            ));
1232        };
1233        let Some(size) = &self.size else {
1234            return Err(Error::Expression(
1235                "Cannot realize an Appoggiatura if there is no size given".to_string(),
1236            ));
1237        };
1238        no_time_to_steal(length)?;
1239        let half = length / 2.0;
1240        let interval = if up { size.reversed()? } else { size.clone() };
1241        let mut leaning = lasting(note, half)?;
1242        leaning.set_pitch(leaning.pitch().transpose(&interval)?);
1243        Ok(Realization {
1244            before: vec![leaning],
1245            main: Some(lasting(note, half)?),
1246            after: Vec::new(),
1247        })
1248    }
1249
1250    fn realize_tremolo(&self, note: &Note, length: FloatType) -> Result<Realization> {
1251        let each = (0.5 as FloatType).powi(IntegerType::from(self.number_of_marks));
1252        let mut repeated = Vec::new();
1253        let mut remaining = note.clone();
1254        let mut left = length;
1255        while left > each {
1256            let mut played = lasting(&remaining, each)?;
1257            left -= each;
1258            remaining = lasting(&remaining, left)?;
1259            tie_split(&mut played, &mut remaining);
1260            repeated.push(played);
1261        }
1262        repeated.push(remaining);
1263        Ok(Realization {
1264            before: repeated,
1265            main: None,
1266            after: Vec::new(),
1267        })
1268    }
1269}
1270
1271/// Ties the two halves of a note split in two, as music21's
1272/// `splitAtQuarterLength` does: the halves are tied to each other, and a tie
1273/// the note already had carries on across them.
1274fn tie_split(first: &mut Note, rest: &mut Note) {
1275    let rest_type = match first.tie().map(Tie::tie_type) {
1276        None => {
1277            first.set_tie(Some(Tie::new(TieType::Start)));
1278            TieType::Stop
1279        }
1280        Some(TieType::Stop) => {
1281            first.set_tie(Some(Tie::new(TieType::Continue)));
1282            TieType::Stop
1283        }
1284        Some(TieType::Start | TieType::Continue) => TieType::Continue,
1285        Some(_) => TieType::Stop,
1286    };
1287    rest.set_tie(Some(Tie::new(rest_type)));
1288}
1289
1290/// Refuses a note with no length for an ornament to take its notes out of.
1291fn no_time_to_steal(length: FloatType) -> Result<()> {
1292    if length == 0.0 {
1293        return Err(Error::Expression(
1294            "Cannot steal time from an object with no duration".to_string(),
1295        ));
1296    }
1297    Ok(())
1298}
1299
1300/// `note` lasting `quarter_length`.
1301fn lasting(note: &Note, quarter_length: FloatType) -> Result<Note> {
1302    let mut copy = note.clone();
1303    copy.set_duration(Duration::new(quarter_length)?);
1304    Ok(copy)
1305}
1306
1307/// The interval from `source` to the step above or below it, spelled by
1308/// `accidental` where there is one and by `key` where not: how music21's
1309/// mordents, trills and turns size themselves.
1310fn neighbour(
1311    source: &Pitch,
1312    up: bool,
1313    accidental: Option<&Accidental>,
1314    key: &KeySignature,
1315) -> Result<Interval> {
1316    let mut ornamental = source.clone();
1317    ornamental.set_written_accidental(None);
1318    ornamental.set_octave_is_implicit(false);
1319    let mut ornamental =
1320        GenericInterval::new(if up { 2 } else { -2 })?.transpose_pitch(&ornamental)?;
1321    let spelled = match accidental {
1322        Some(accidental) => Some(accidental.clone()),
1323        None => key.accidental_by_step(ornamental.step().as_char())?,
1324    };
1325    ornamental.set_written_accidental(spelled);
1326    Interval::between_pitches(source, &ornamental)
1327}
1328
1329/// A number written as Python writes a float: `0.5`, `1.0`.
1330pub(crate) fn python_float(value: FloatType) -> String {
1331    if value.fract() == 0.0 {
1332        format!("{value:.1}")
1333    } else {
1334        value.to_string()
1335    }
1336}
1337
1338/// Which way up a fermata is drawn: music21's `Fermata.type`.
1339#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
1340#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1341pub enum FermataType {
1342    /// The arc opening downward, above the staff: MusicXML's `upright`.
1343    Upright,
1344    /// The arc opening upward: MusicXML's `inverted`, and music21's default.
1345    #[default]
1346    Inverted,
1347}
1348
1349impl FermataType {
1350    /// The name music21 and MusicXML give it.
1351    pub fn as_str(self) -> &'static str {
1352        match self {
1353            Self::Upright => "upright",
1354            Self::Inverted => "inverted",
1355        }
1356    }
1357}
1358
1359/// A pause of unmeasured length over a note: music21's `Fermata`.
1360#[derive(Clone, Debug, Default, PartialEq, Eq)]
1361#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1362#[must_use]
1363pub struct Fermata {
1364    fermata_type: FermataType,
1365    shape: Option<String>,
1366}
1367
1368impl Fermata {
1369    /// A normal fermata, drawn inverted as music21's starts out.
1370    pub fn new() -> Self {
1371        Self::default()
1372    }
1373
1374    /// Which way up it is drawn.
1375    pub fn fermata_type(&self) -> FermataType {
1376        self.fermata_type
1377    }
1378
1379    /// Says which way up it is drawn.
1380    pub fn set_fermata_type(&mut self, fermata_type: FermataType) {
1381        self.fermata_type = fermata_type;
1382    }
1383
1384    /// Its shape, `angled` or `square`, or nothing for the normal arc:
1385    /// music21's `shape`, which it writes as `normal`.
1386    pub fn shape(&self) -> Option<&str> {
1387        self.shape.as_deref()
1388    }
1389
1390    /// Sets its shape; `normal` is the arc and is kept as nothing.
1391    pub fn set_shape(&mut self, shape: Option<String>) {
1392        self.shape = shape.filter(|shape| shape != "normal");
1393    }
1394}
1395
1396/// How a chord's notes are spread: music21's `ArpeggioMark.type`.
1397#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
1398#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1399pub enum ArpeggioType {
1400    /// A wavy line, bottom to top.
1401    #[default]
1402    Normal,
1403    /// A wavy line with an arrow pointing up.
1404    Up,
1405    /// A wavy line with an arrow pointing down.
1406    Down,
1407    /// A bracket: this chord is not spread, among ones that are.
1408    NonArpeggio,
1409}
1410
1411impl ArpeggioType {
1412    /// music21's name for it.
1413    pub fn as_str(self) -> &'static str {
1414        match self {
1415            Self::Normal => "normal",
1416            Self::Up => "up",
1417            Self::Down => "down",
1418            Self::NonArpeggio => "non-arpeggio",
1419        }
1420    }
1421
1422    /// Reads music21's name for it.
1423    pub fn from_name(name: &str) -> Result<Self> {
1424        match name {
1425            "normal" => Ok(Self::Normal),
1426            "up" => Ok(Self::Up),
1427            "down" => Ok(Self::Down),
1428            "non-arpeggio" => Ok(Self::NonArpeggio),
1429            other => Err(Error::Value(format!(
1430                "Arpeggio type must be \"normal\", \"up\", \"down\", or \"non-arpeggio\", not '{other}'."
1431            ))),
1432        }
1433    }
1434}
1435
1436/// Words written over or under the staff: music21's `TextExpression`, a
1437/// score's *dolce* or *cresc.* or a movement's *Grave* where it is not read
1438/// as a tempo.
1439#[derive(Clone, Debug, Default, PartialEq, Eq)]
1440#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1441#[must_use]
1442pub struct TextExpression {
1443    content: String,
1444    #[cfg_attr(feature = "serde", serde(default))]
1445    placement: crate::display::Drawn<Option<crate::notation::Placement>>,
1446}
1447
1448impl TextExpression {
1449    /// Words to write.
1450    pub fn new(content: impl Into<String>) -> Self {
1451        Self {
1452            content: content.into(),
1453            placement: crate::display::Drawn(None),
1454        }
1455    }
1456
1457    /// The words: music21's `content`.
1458    pub fn content(&self) -> &str {
1459        &self.content
1460    }
1461
1462    /// Changes the words.
1463    pub fn set_content(&mut self, content: impl Into<String>) {
1464        self.content = content.into();
1465    }
1466
1467    /// Which side of the staff the words are written on, where the score
1468    /// says.
1469    pub fn placement(&self) -> Option<crate::notation::Placement> {
1470        self.placement.0
1471    }
1472
1473    /// Says which side of the staff the words are written on.
1474    pub fn set_placement(&mut self, placement: Option<crate::notation::Placement>) {
1475        self.placement.0 = placement;
1476    }
1477}
1478
1479/// A letter or number marking a place to rehearse from: music21's
1480/// `RehearsalMark`.
1481#[derive(Clone, Debug, Default, PartialEq, Eq)]
1482#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1483#[must_use]
1484pub struct RehearsalMark {
1485    content: String,
1486    #[cfg_attr(feature = "serde", serde(default))]
1487    placement: crate::display::Drawn<Option<crate::notation::Placement>>,
1488    #[cfg_attr(feature = "serde", serde(default))]
1489    enclosure: crate::display::Drawn<Option<String>>,
1490}
1491
1492impl RehearsalMark {
1493    /// A mark reading as given, `A` or `12`.
1494    pub fn new(content: impl Into<String>) -> Self {
1495        Self {
1496            content: content.into(),
1497            placement: crate::display::Drawn(None),
1498            enclosure: crate::display::Drawn(None),
1499        }
1500    }
1501
1502    /// What the mark reads: music21's `content`.
1503    pub fn content(&self) -> &str {
1504        &self.content
1505    }
1506
1507    /// Changes what the mark reads.
1508    pub fn set_content(&mut self, content: impl Into<String>) {
1509        self.content = content.into();
1510    }
1511
1512    /// Which side of the staff the mark is written on, where the score
1513    /// says.
1514    pub fn placement(&self) -> Option<crate::notation::Placement> {
1515        self.placement.0
1516    }
1517
1518    /// Says which side of the staff the mark is written on.
1519    pub fn set_placement(&mut self, placement: Option<crate::notation::Placement>) {
1520        self.placement.0 = placement;
1521    }
1522
1523    /// What is drawn round the mark, `square` or `circle`, where the score
1524    /// says: music21's `style.enclosure`.
1525    pub fn enclosure(&self) -> Option<&str> {
1526        self.enclosure.0.as_deref()
1527    }
1528
1529    /// Says what is drawn round the mark.
1530    pub fn set_enclosure(&mut self, enclosure: Option<String>) {
1531        self.enclosure.0 = enclosure;
1532    }
1533}
1534
1535/// Something written on a note that is not its pitch or length: an entry
1536/// of music21's `GeneralNote.expressions`.
1537#[derive(Clone, Debug, PartialEq)]
1538#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1539pub enum Expression {
1540    /// An ornament: a mordent, a trill, a turn and the rest. Boxed, as an
1541    /// ornament is large and most expressions are not one.
1542    Ornament(Box<Ornament>),
1543    /// A fermata.
1544    Fermata(Fermata),
1545    /// A chord spread from one end to the other.
1546    Arpeggio(ArpeggioType),
1547}
1548
1549impl From<Ornament> for Expression {
1550    fn from(value: Ornament) -> Self {
1551        Self::Ornament(Box::new(value))
1552    }
1553}
1554
1555impl From<Fermata> for Expression {
1556    fn from(value: Fermata) -> Self {
1557        Self::Fermata(value)
1558    }
1559}
1560
1561impl Expression {
1562    /// Which piece of a note split across a tie keeps this expression:
1563    /// music21's `tieAttach`, `"first"`, `"last"` or `"all"`. A fermata stays
1564    /// on the last piece, an arpeggio on the first, and an ornament where it
1565    /// says.
1566    pub fn tie_attach(&self) -> &str {
1567        match self {
1568            Self::Ornament(ornament) => ornament.tie_attach(),
1569            Self::Fermata(_) => "last",
1570            Self::Arpeggio(_) => "first",
1571        }
1572    }
1573
1574    /// Whether this is a trill, the one expression music21 hands the pieces
1575    /// of a split note to: only its `Trill` has `splitClient`.
1576    fn is_trill(&self) -> bool {
1577        matches!(self, Self::Ornament(ornament) if ornament.is_a("Trill"))
1578    }
1579}
1580
1581/// The expressions of a note split in two, shared between the pieces as
1582/// music21's `splitAtQuarterLength` shares them: a trill goes onto the first
1583/// piece by [`Ornament::split_client`], anything else where its
1584/// [`Expression::tie_attach`] says. The trill extension music21 makes
1585/// alongside is not kept, as its `makeTies` keeps none.
1586pub(crate) fn split_expressions(expressions: &[Expression]) -> (Vec<Expression>, Vec<Expression>) {
1587    let mut first = Vec::new();
1588    let mut second = Vec::new();
1589    for expression in expressions {
1590        if expression.is_trill() {
1591            first.push(expression.clone());
1592            continue;
1593        }
1594        match expression.tie_attach() {
1595            "first" => first.push(expression.clone()),
1596            "last" => second.push(expression.clone()),
1597            _ => {
1598                first.push(expression.clone());
1599                second.push(expression.clone());
1600            }
1601        }
1602    }
1603    (first, second)
1604}
1605
1606/// Every ornament on `note` played in turn: music21's
1607/// `expressions.realizeOrnaments`, where each ornament realizes what the
1608/// one before left of the note and an ornament that takes the whole note
1609/// ends the walk.
1610///
1611/// music21's `stream.makeNotation.realizeOrnaments` is a different
1612/// function of the same name: it hands each ornament the note as it
1613/// stands, and writes the realizations into a stream of its own.
1614///
1615/// # Errors
1616///
1617/// Any ornament that cannot realize what it is given.
1618pub fn realize_ornaments(
1619    note: &Note,
1620    ornaments: &[Ornament],
1621    key: &KeySignature,
1622) -> Result<Vec<Note>> {
1623    let mut before = Vec::new();
1624    let mut after: Vec<Note> = Vec::new();
1625    let mut current = Some(note.clone());
1626    for ornament in ornaments {
1627        let Some(main) = current.take() else {
1628            break;
1629        };
1630        let played = ornament.realize(&main, key)?;
1631        before.extend(played.before);
1632        after.extend(played.after);
1633        current = played.main;
1634    }
1635    before.extend(current);
1636    before.extend(after);
1637    Ok(before)
1638}
1639
1640#[cfg(test)]
1641mod tests {
1642    use super::*;
1643
1644    fn written(notes: Vec<Note>) -> Vec<String> {
1645        notes
1646            .iter()
1647            .map(|note| {
1648                let length = note.duration().map_or(1.0, Duration::quarter_length);
1649                match note.tie() {
1650                    Some(tie) => format!(
1651                        "{} {length} {}",
1652                        note.pitch().name_with_octave(),
1653                        tie.tie_type().as_str()
1654                    ),
1655                    None => format!("{} {length}", note.pitch().name_with_octave()),
1656                }
1657            })
1658            .collect()
1659    }
1660
1661    /// Every answer here is music21's own.
1662    #[test]
1663    fn an_ornament_answers_what_music21_s_answers() {
1664        let directions = [
1665            (OrnamentKind::GeneralMordent, None),
1666            (OrnamentKind::Mordent, Some(IntervalDirection::Descending)),
1667            (
1668                OrnamentKind::InvertedMordent,
1669                Some(IntervalDirection::Ascending),
1670            ),
1671            (OrnamentKind::Trill, Some(IntervalDirection::Ascending)),
1672            (
1673                OrnamentKind::InvertedTrill,
1674                Some(IntervalDirection::Descending),
1675            ),
1676            (OrnamentKind::Shake, Some(IntervalDirection::Ascending)),
1677            (OrnamentKind::GeneralAppoggiatura, None),
1678            (
1679                OrnamentKind::Appoggiatura,
1680                Some(IntervalDirection::Descending),
1681            ),
1682            (
1683                OrnamentKind::InvertedAppoggiatura,
1684                Some(IntervalDirection::Ascending),
1685            ),
1686            (OrnamentKind::Turn, None),
1687        ];
1688        for (kind, direction) in directions {
1689            assert_eq!(Ornament::of_kind(kind).direction(), direction, "{kind:?}");
1690        }
1691
1692        let key = KeySignature::new(0);
1693        let mut quarter = Note::from_name("C4").unwrap();
1694        quarter.set_duration(Duration::new(1.0).unwrap());
1695        let tremolo = Ornament::of_kind(OrnamentKind::Tremolo);
1696        let played = tremolo.realize(&quarter, &key).unwrap().into_notes();
1697        assert_eq!(played.len(), 8);
1698        assert_eq!(
1699            written(played)[..2],
1700            ["C4 0.125 start", "C4 0.125 continue"]
1701        );
1702
1703        let mut half_step = Ornament::of_kind(OrnamentKind::HalfStepMordent);
1704        assert!(
1705            half_step
1706                .set_accidental(Accidental::new("sharp").ok())
1707                .is_err()
1708        );
1709
1710        let mut trill = Ornament::of_kind(OrnamentKind::Trill);
1711        trill.set_nachschlag(true);
1712        let played = written(trill.realize(&quarter, &key).unwrap().into_notes());
1713        assert_eq!(
1714            played,
1715            [
1716                "C4 0.125", "D4 0.125", "C4 0.125", "D4 0.125", "C4 0.125", "D4 0.125", "C4 0.125",
1717                "B3 0.125"
1718            ]
1719        );
1720    }
1721}