Skip to main content

music21_rs/
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/// A silent musical event with a duration.
8///
9/// A rest may still carry words: a syllable written under a rest is how a
10/// score says a line is spoken there, or how a verse number sits at the start
11/// of a phrase that opens on a rest. music21 writes the lyric methods once on
12/// `GeneralNote`, and a rest has them as a note does.
13///
14/// Two rests are equal when they last as long; what is written under them
15/// does not count, as it does not in music21.
16#[derive(Clone, Debug)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18#[must_use]
19pub struct Rest {
20    duration: Duration,
21    #[cfg_attr(feature = "serde", serde(default))]
22    lyrics: Vec<Lyric>,
23    #[cfg_attr(feature = "serde", serde(default))]
24    hidden: bool,
25    #[cfg_attr(feature = "serde", serde(default))]
26    expressions: Vec<Expression>,
27    #[cfg_attr(feature = "serde", serde(default))]
28    articulations: Vec<Articulation>,
29    #[cfg_attr(feature = "serde", serde(default))]
30    step_shift: IntegerType,
31    #[cfg_attr(feature = "serde", serde(default))]
32    size: Option<crate::notation::NoteSize>,
33    #[cfg_attr(feature = "serde", serde(default))]
34    tie: Option<crate::notation::Tie>,
35    #[cfg_attr(feature = "serde", serde(default))]
36    full_measure: Option<bool>,
37}
38
39impl PartialEq for Rest {
40    fn eq(&self, other: &Self) -> bool {
41        self.duration == other.duration
42    }
43}
44
45impl Rest {
46    /// Creates a rest with the supplied duration.
47    pub fn new(duration: Duration) -> Self {
48        Self {
49            duration,
50            lyrics: Vec::new(),
51            hidden: false,
52            expressions: Vec::new(),
53            articulations: Vec::new(),
54            step_shift: 0,
55            size: None,
56            tie: None,
57            full_measure: None,
58        }
59    }
60
61    /// Whether the rest stands for the whole of its measure, however long
62    /// it is written: music21's `fullMeasure`, nothing for its `auto`. The
63    /// MusicXML reader says so where music21's does.
64    pub fn full_measure(&self) -> Option<bool> {
65        self.full_measure
66    }
67
68    /// Says whether the rest stands for the whole of its measure.
69    pub fn set_full_measure(&mut self, full_measure: Option<bool>) {
70        self.full_measure = full_measure;
71    }
72
73    /// This rest written as a grace note's value and lasting no time:
74    /// music21's `getGrace`, which a rest has as a note does.
75    pub fn grace_note(&self, appoggiatura: bool) -> Self {
76        let mut grace = self.clone();
77        grace.set_duration(self.duration.grace_duration_as(appoggiatura));
78        grace
79    }
80
81    /// The tie written on the rest, which music21 lets a rest carry and a
82    /// score now and then writes.
83    pub fn tie(&self) -> Option<&crate::notation::Tie> {
84        self.tie.as_ref()
85    }
86
87    /// Writes a tie on the rest, or takes it off.
88    pub fn set_tie(&mut self, tie: Option<crate::notation::Tie>) {
89        self.tie = tie;
90    }
91
92    /// How large the rest is drawn, where a score says, as a cue part's
93    /// rests are drawn small.
94    pub fn size(&self) -> Option<crate::notation::NoteSize> {
95        self.size
96    }
97
98    /// Says how large the rest is drawn.
99    pub fn set_size(&mut self, size: Option<crate::notation::NoteSize>) {
100        self.size = size;
101    }
102
103    /// How many staff steps above the middle line the rest is drawn, below
104    /// where negative: music21's `stepShift`, which a score uses to keep one
105    /// voice's rests out of another's way.
106    pub fn step_shift(&self) -> IntegerType {
107        self.step_shift
108    }
109
110    /// Says how many staff steps from the middle line it is drawn.
111    pub fn set_step_shift(&mut self, shift: IntegerType) {
112        self.step_shift = shift;
113    }
114
115    /// The fermatas and other marks written over the rest: music21's
116    /// `expressions`, which a rest has as a note does.
117    pub fn expressions(&self) -> &[Expression] {
118        &self.expressions
119    }
120
121    /// The same, to be changed.
122    pub fn expressions_mut(&mut self) -> &mut Vec<Expression> {
123        &mut self.expressions
124    }
125
126    /// The articulations written on the rest: music21's `articulations`.
127    pub fn articulations(&self) -> &[Articulation] {
128        &self.articulations
129    }
130
131    /// The same, to be changed.
132    pub fn articulations_mut(&mut self) -> &mut Vec<Articulation> {
133        &mut self.articulations
134    }
135
136    /// Whether it is left off the printed page, keeping its place and its
137    /// time: music21's `style.hideObjectOnPrint`, which a score uses for a
138    /// rest that only fills out a voice.
139    pub fn hidden(&self) -> bool {
140        self.hidden
141    }
142
143    /// Says whether it is left off the printed page.
144    pub fn set_hidden(&mut self, hidden: bool) {
145        self.hidden = hidden;
146    }
147
148    /// Creates a rest from a quarter-length value.
149    pub fn from_quarter_length(quarter_length: crate::FloatType) -> crate::Result<Self> {
150        Ok(Self::new(Duration::new(quarter_length)?))
151    }
152
153    /// Returns the rest duration.
154    pub fn duration(&self) -> &Duration {
155        &self.duration
156    }
157
158    /// Updates the rest duration.
159    pub fn set_duration(&mut self, duration: Duration) {
160        self.duration = duration;
161    }
162
163    /// Returns the duration in quarter lengths.
164    pub fn quarter_length(&self) -> crate::FloatType {
165        self.duration.quarter_length()
166    }
167
168    /// The most complete name of the rest, its length included: music21's
169    /// `fullName`, `Dotted Quarter Rest`.
170    pub fn full_name(&self) -> String {
171        format!("{} Rest", self.duration.full_name())
172    }
173
174    /// The syllables written under the rest, one per verse.
175    pub fn lyrics(&self) -> &[Lyric] {
176        &self.lyrics
177    }
178
179    /// The syllables written under the rest, for editing in place.
180    pub fn lyrics_mut(&mut self) -> &mut Vec<Lyric> {
181        &mut self.lyrics
182    }
183
184    /// The text of every verse, one per line: music21's `lyric`.
185    pub fn lyric(&self) -> Option<String> {
186        verses::joined(&self.lyrics)
187    }
188
189    /// Replaces every verse with one per line of the text, or clears them
190    /// with `None`: music21's `lyric` setter.
191    pub fn set_lyric(&mut self, lyric: Option<&str>) {
192        verses::set(&mut self.lyrics, lyric);
193    }
194
195    /// Adds a syllable as a verse: music21's `addLyric`, which a rest has
196    /// as a note has it. See [`crate::Note::add_lyric`].
197    pub fn add_lyric(&mut self, text: &str, number: Option<IntegerType>, apply_raw: bool) {
198        verses::add(&mut self.lyrics, text, number, apply_raw);
199    }
200
201    /// Puts a syllable in front of the verse at `index`: music21's
202    /// `insertLyric`.
203    pub fn insert_lyric(&mut self, text: &str, index: usize, apply_raw: bool) {
204        verses::insert(&mut self.lyrics, text, index, apply_raw);
205    }
206}
207
208impl Default for Rest {
209    fn default() -> Self {
210        Self::new(Duration::default())
211    }
212}
213
214impl From<Duration> for Rest {
215    fn from(value: Duration) -> Self {
216        Self::new(value)
217    }
218}
219
220#[cfg(test)]
221mod tests {
222    use super::*;
223
224    #[test]
225    fn rest_has_duration() {
226        let rest = Rest::from_quarter_length(2.0).unwrap();
227        assert_eq!(rest.quarter_length(), 2.0);
228    }
229
230    #[test]
231    fn a_rest_is_named_by_its_length() {
232        assert_eq!(
233            Rest::from_quarter_length(1.5).unwrap().full_name(),
234            "Dotted Quarter Rest"
235        );
236        assert_eq!(Rest::new(Duration::whole()).full_name(), "Whole Rest");
237    }
238
239    #[test]
240    fn a_rest_carries_verses_as_a_note_does_and_they_do_not_make_it_unequal() {
241        let mut rest = Rest::from_quarter_length(1.0).unwrap();
242        rest.add_lyric("hel-", None, false);
243        rest.add_lyric("two", None, false);
244        rest.insert_lyric("one", 0, false);
245        assert_eq!(rest.lyric().as_deref(), Some("one\nhel\ntwo"));
246        assert_eq!(
247            rest.lyrics().iter().map(Lyric::number).collect::<Vec<_>>(),
248            [1, 2, 3]
249        );
250        assert_eq!(rest, Rest::from_quarter_length(1.0).unwrap());
251        rest.set_lyric(None);
252        assert!(rest.lyrics().is_empty());
253    }
254
255    #[test]
256    fn rest_supports_default_from_and_updates() {
257        let mut rest = Rest::default();
258        assert_eq!(rest.quarter_length(), 1.0);
259
260        rest.set_duration(Duration::whole());
261        assert_eq!(rest.duration(), &Duration::whole());
262
263        let half_rest = Rest::from(Duration::half());
264        assert_eq!(half_rest.quarter_length(), 2.0);
265        assert!(Rest::from_quarter_length(crate::FloatType::NAN).is_err());
266    }
267}