Skip to main content

music21/
rest.rs

1use crate::articulations::Articulation;
2use crate::defaults::IntegerType;
3use crate::duration::Duration;
4use crate::expressions::Expression;
5use crate::notation::{Lyric, verses};
6
7/// What a rest says of its measure: music21's `fullMeasure`, which is
8/// `True`, `False`, `'auto'` or `'always'`.
9///
10/// ```
11/// use music21::{Duration, FullMeasure, Rest};
12///
13/// let mut rest = Rest::new(Duration::half());
14/// assert_eq!(rest.full_measure(), FullMeasure::Auto);
15/// rest.set_full_measure(FullMeasure::Always);
16/// assert_eq!(rest.full_measure(), FullMeasure::Always);
17/// ```
18#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
19#[cfg_attr(feature = "serde", derive(serde::Serialize))]
20pub enum FullMeasure {
21    /// music21's `'auto'`: a whole-measure rest where it fills its measure.
22    #[default]
23    Auto,
24    /// music21's `True`: it stands for its whole measure. Braille writes it
25    /// as a measure rest whatever its length.
26    Yes,
27    /// music21's `False`: it is only as long as it is written.
28    No,
29    /// music21's `'always'`: MusicXML writes it as a measure rest whatever
30    /// its length; braille writes it at its length.
31    Always,
32}
33
34/// Reads a saved `FullMeasure`, or what was saved before there was one:
35/// `null`, `true` or `false`.
36#[cfg(feature = "serde")]
37impl<'de> serde::Deserialize<'de> for FullMeasure {
38    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
39        #[derive(serde::Deserialize)]
40        enum Named {
41            Auto,
42            Yes,
43            No,
44            Always,
45        }
46
47        #[derive(serde::Deserialize)]
48        #[serde(untagged)]
49        enum Saved {
50            Flag(Option<bool>),
51            Named(Named),
52        }
53
54        Ok(match Saved::deserialize(deserializer)? {
55            Saved::Flag(None) | Saved::Named(Named::Auto) => Self::Auto,
56            Saved::Flag(Some(true)) | Saved::Named(Named::Yes) => Self::Yes,
57            Saved::Flag(Some(false)) | Saved::Named(Named::No) => Self::No,
58            Saved::Named(Named::Always) => Self::Always,
59        })
60    }
61}
62
63/// A silent musical event with a duration.
64///
65/// A rest may still carry words: a syllable written under a rest is how a
66/// score says a line is spoken there, or how a verse number sits at the start
67/// of a phrase that opens on a rest. music21 writes the lyric methods once on
68/// `GeneralNote`, and a rest has them as a note does.
69///
70/// Two rests are equal when they last as long; what is written under them
71/// does not count, as it does not in music21.
72#[derive(Clone, Debug)]
73#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
74#[must_use]
75pub struct Rest {
76    duration: Duration,
77    #[cfg_attr(feature = "serde", serde(default))]
78    lyrics: Vec<Lyric>,
79    #[cfg_attr(feature = "serde", serde(default))]
80    hidden: bool,
81    #[cfg_attr(feature = "serde", serde(default))]
82    expressions: Vec<Expression>,
83    #[cfg_attr(feature = "serde", serde(default))]
84    articulations: Vec<Articulation>,
85    #[cfg_attr(feature = "serde", serde(default))]
86    step_shift: IntegerType,
87    #[cfg_attr(feature = "serde", serde(default))]
88    size: Option<crate::notation::NoteSize>,
89    #[cfg_attr(feature = "serde", serde(default))]
90    tie: Option<crate::notation::Tie>,
91    #[cfg_attr(feature = "serde", serde(default))]
92    full_measure: FullMeasure,
93    #[cfg_attr(feature = "serde", serde(default))]
94    color: Option<String>,
95    #[cfg_attr(feature = "serde", serde(default))]
96    id: Option<String>,
97    #[cfg_attr(feature = "serde", serde(default))]
98    beams: Option<crate::notation::Beams>,
99}
100
101impl PartialEq for Rest {
102    fn eq(&self, other: &Self) -> bool {
103        self.duration == other.duration
104    }
105}
106
107impl Rest {
108    /// Creates a rest with the supplied duration.
109    pub fn new(duration: Duration) -> Self {
110        Self {
111            duration,
112            lyrics: Vec::new(),
113            hidden: false,
114            expressions: Vec::new(),
115            articulations: Vec::new(),
116            step_shift: 0,
117            size: None,
118            tie: None,
119            full_measure: FullMeasure::Auto,
120            color: None,
121            id: None,
122            beams: None,
123        }
124    }
125
126    /// The beams music21's makeBeams handed the rest, empty, where it
127    /// beamed the line the rest stands in; none where nothing did.
128    pub fn beams(&self) -> Option<&crate::notation::Beams> {
129        self.beams.as_ref()
130    }
131
132    /// Hands the rest beams, or takes them away.
133    pub fn set_beams(&mut self, beams: Option<crate::notation::Beams>) {
134        self.beams = beams;
135    }
136
137    /// The name the rest is known by, where a reader found one: music21's
138    /// `id`, from MEI's `xml:id`.
139    pub fn id(&self) -> Option<&str> {
140        self.id.as_deref()
141    }
142
143    /// Names the rest, or takes its name away.
144    pub fn set_id(&mut self, id: Option<String>) {
145        self.id = id;
146    }
147
148    /// What the rest says of its measure: music21's `fullMeasure`. The
149    /// MusicXML reader says `Yes` where music21's does.
150    pub fn full_measure(&self) -> FullMeasure {
151        self.full_measure
152    }
153
154    /// Says what the rest says of its measure.
155    pub fn set_full_measure(&mut self, full_measure: FullMeasure) {
156        self.full_measure = full_measure;
157    }
158
159    /// This rest written as a grace note's value and lasting no time:
160    /// music21's `getGrace`, which a rest has as a note does.
161    pub fn grace_note(&self, appoggiatura: bool) -> Self {
162        let mut grace = self.clone();
163        grace.set_duration(self.duration.grace_duration_as(appoggiatura));
164        grace
165    }
166
167    /// The tie written on the rest, which music21 lets a rest carry and a
168    /// score now and then writes.
169    pub fn tie(&self) -> Option<&crate::notation::Tie> {
170        self.tie.as_ref()
171    }
172
173    /// Writes a tie on the rest, or takes it off.
174    pub fn set_tie(&mut self, tie: Option<crate::notation::Tie>) {
175        self.tie = tie;
176    }
177
178    /// The colour the rest is written in, if one was said: music21 keeps
179    /// this on the rest's style.
180    ///
181    /// ```
182    /// use music21::Rest;
183    ///
184    /// let mut rest = Rest::default();
185    /// assert_eq!(rest.color(), None);
186    /// rest.set_color(Some("red".to_string()));
187    /// assert_eq!(rest.color(), Some("red"));
188    /// ```
189    pub fn color(&self) -> Option<&str> {
190        self.color.as_deref()
191    }
192
193    /// Sets the colour the rest is written in.
194    pub fn set_color(&mut self, color: Option<String>) {
195        self.color = color;
196    }
197
198    /// How large the rest is drawn, where a score says, as a cue part's
199    /// rests are drawn small.
200    pub fn size(&self) -> Option<crate::notation::NoteSize> {
201        self.size
202    }
203
204    /// Says how large the rest is drawn.
205    pub fn set_size(&mut self, size: Option<crate::notation::NoteSize>) {
206        self.size = size;
207    }
208
209    /// How many staff steps above the middle line the rest is drawn, below
210    /// where negative: music21's `stepShift`, which a score uses to keep one
211    /// voice's rests out of another's way.
212    pub fn step_shift(&self) -> IntegerType {
213        self.step_shift
214    }
215
216    /// Says how many staff steps from the middle line it is drawn.
217    pub fn set_step_shift(&mut self, shift: IntegerType) {
218        self.step_shift = shift;
219    }
220
221    /// The fermatas and other marks written over the rest: music21's
222    /// `expressions`, which a rest has as a note does.
223    pub fn expressions(&self) -> &[Expression] {
224        &self.expressions
225    }
226
227    /// The same, to be changed.
228    pub fn expressions_mut(&mut self) -> &mut Vec<Expression> {
229        &mut self.expressions
230    }
231
232    /// The articulations written on the rest: music21's `articulations`.
233    pub fn articulations(&self) -> &[Articulation] {
234        &self.articulations
235    }
236
237    /// The same, to be changed.
238    pub fn articulations_mut(&mut self) -> &mut Vec<Articulation> {
239        &mut self.articulations
240    }
241
242    /// Whether it is left off the printed page, keeping its place and its
243    /// time: music21's `style.hideObjectOnPrint`, which a score uses for a
244    /// rest that only fills out a voice.
245    pub fn hidden(&self) -> bool {
246        self.hidden
247    }
248
249    /// Says whether it is left off the printed page.
250    pub fn set_hidden(&mut self, hidden: bool) {
251        self.hidden = hidden;
252    }
253
254    /// Creates a rest from a quarter-length value.
255    pub fn from_quarter_length(quarter_length: crate::FloatType) -> crate::Result<Self> {
256        Ok(Self::new(Duration::new(quarter_length)?))
257    }
258
259    /// Returns the rest duration.
260    pub fn duration(&self) -> &Duration {
261        &self.duration
262    }
263
264    /// Updates the rest duration.
265    pub fn set_duration(&mut self, duration: Duration) {
266        self.duration = duration;
267    }
268
269    /// Returns the duration in quarter lengths.
270    pub fn quarter_length(&self) -> crate::FloatType {
271        self.duration.quarter_length()
272    }
273
274    /// The most complete name of the rest, its length included: music21's
275    /// `fullName`, `Dotted Quarter Rest`.
276    pub fn full_name(&self) -> String {
277        format!("{} Rest", self.duration.full_name())
278    }
279
280    /// The syllables written under the rest, one per verse.
281    pub fn lyrics(&self) -> &[Lyric] {
282        &self.lyrics
283    }
284
285    /// The syllables written under the rest, for editing in place.
286    pub fn lyrics_mut(&mut self) -> &mut Vec<Lyric> {
287        &mut self.lyrics
288    }
289
290    /// The text of every verse, one per line: music21's `lyric`.
291    pub fn lyric(&self) -> Option<String> {
292        verses::joined(&self.lyrics)
293    }
294
295    /// Replaces every verse with one per line of the text, or clears them
296    /// with `None`: music21's `lyric` setter.
297    pub fn set_lyric(&mut self, lyric: Option<&str>) {
298        verses::set(&mut self.lyrics, lyric);
299    }
300
301    /// Adds a syllable as a verse: music21's `addLyric`, which a rest has
302    /// as a note has it. See [`crate::Note::add_lyric`].
303    pub fn add_lyric(&mut self, text: &str, number: Option<IntegerType>, apply_raw: bool) {
304        verses::add(&mut self.lyrics, text, number, apply_raw);
305    }
306
307    /// Puts a syllable in front of the verse at `index`: music21's
308    /// `insertLyric`.
309    pub fn insert_lyric(&mut self, text: &str, index: usize, apply_raw: bool) {
310        verses::insert(&mut self.lyrics, text, index, apply_raw);
311    }
312}
313
314impl Default for Rest {
315    fn default() -> Self {
316        Self::new(Duration::default())
317    }
318}
319
320impl From<Duration> for Rest {
321    fn from(value: Duration) -> Self {
322        Self::new(value)
323    }
324}
325
326#[cfg(test)]
327mod tests {
328    use super::*;
329
330    #[test]
331    fn rest_has_duration() {
332        let rest = Rest::from_quarter_length(2.0).unwrap();
333        assert_eq!(rest.quarter_length(), 2.0);
334    }
335
336    #[test]
337    fn a_rest_is_named_by_its_length() {
338        assert_eq!(
339            Rest::from_quarter_length(1.5).unwrap().full_name(),
340            "Dotted Quarter Rest"
341        );
342        assert_eq!(Rest::new(Duration::whole()).full_name(), "Whole Rest");
343    }
344
345    #[test]
346    fn a_rest_carries_verses_as_a_note_does_and_they_do_not_make_it_unequal() {
347        let mut rest = Rest::from_quarter_length(1.0).unwrap();
348        rest.add_lyric("hel-", None, false);
349        rest.add_lyric("two", None, false);
350        rest.insert_lyric("one", 0, false);
351        assert_eq!(rest.lyric().as_deref(), Some("one\nhel\ntwo"));
352        assert_eq!(
353            rest.lyrics().iter().map(Lyric::number).collect::<Vec<_>>(),
354            [1, 2, 3]
355        );
356        assert_eq!(rest, Rest::from_quarter_length(1.0).unwrap());
357        rest.set_lyric(None);
358        assert!(rest.lyrics().is_empty());
359    }
360
361    #[test]
362    fn rest_supports_default_from_and_updates() {
363        let mut rest = Rest::default();
364        assert_eq!(rest.quarter_length(), 1.0);
365
366        rest.set_duration(Duration::whole());
367        assert_eq!(rest.duration(), &Duration::whole());
368
369        let half_rest = Rest::from(Duration::half());
370        assert_eq!(half_rest.quarter_length(), 2.0);
371        assert!(Rest::from_quarter_length(crate::FloatType::NAN).is_err());
372    }
373}