1use crate::articulations::Articulation;
2use crate::defaults::IntegerType;
3use crate::duration::Duration;
4use crate::expressions::Expression;
5use crate::notation::{Lyric, verses};
6
7#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
19#[cfg_attr(feature = "serde", derive(serde::Serialize))]
20pub enum FullMeasure {
21 #[default]
23 Auto,
24 Yes,
27 No,
29 Always,
32}
33
34#[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#[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 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 pub fn beams(&self) -> Option<&crate::notation::Beams> {
129 self.beams.as_ref()
130 }
131
132 pub fn set_beams(&mut self, beams: Option<crate::notation::Beams>) {
134 self.beams = beams;
135 }
136
137 pub fn id(&self) -> Option<&str> {
140 self.id.as_deref()
141 }
142
143 pub fn set_id(&mut self, id: Option<String>) {
145 self.id = id;
146 }
147
148 pub fn full_measure(&self) -> FullMeasure {
151 self.full_measure
152 }
153
154 pub fn set_full_measure(&mut self, full_measure: FullMeasure) {
156 self.full_measure = full_measure;
157 }
158
159 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 pub fn tie(&self) -> Option<&crate::notation::Tie> {
170 self.tie.as_ref()
171 }
172
173 pub fn set_tie(&mut self, tie: Option<crate::notation::Tie>) {
175 self.tie = tie;
176 }
177
178 pub fn color(&self) -> Option<&str> {
190 self.color.as_deref()
191 }
192
193 pub fn set_color(&mut self, color: Option<String>) {
195 self.color = color;
196 }
197
198 pub fn size(&self) -> Option<crate::notation::NoteSize> {
201 self.size
202 }
203
204 pub fn set_size(&mut self, size: Option<crate::notation::NoteSize>) {
206 self.size = size;
207 }
208
209 pub fn step_shift(&self) -> IntegerType {
213 self.step_shift
214 }
215
216 pub fn set_step_shift(&mut self, shift: IntegerType) {
218 self.step_shift = shift;
219 }
220
221 pub fn expressions(&self) -> &[Expression] {
224 &self.expressions
225 }
226
227 pub fn expressions_mut(&mut self) -> &mut Vec<Expression> {
229 &mut self.expressions
230 }
231
232 pub fn articulations(&self) -> &[Articulation] {
234 &self.articulations
235 }
236
237 pub fn articulations_mut(&mut self) -> &mut Vec<Articulation> {
239 &mut self.articulations
240 }
241
242 pub fn hidden(&self) -> bool {
246 self.hidden
247 }
248
249 pub fn set_hidden(&mut self, hidden: bool) {
251 self.hidden = hidden;
252 }
253
254 pub fn from_quarter_length(quarter_length: crate::FloatType) -> crate::Result<Self> {
256 Ok(Self::new(Duration::new(quarter_length)?))
257 }
258
259 pub fn duration(&self) -> &Duration {
261 &self.duration
262 }
263
264 pub fn set_duration(&mut self, duration: Duration) {
266 self.duration = duration;
267 }
268
269 pub fn quarter_length(&self) -> crate::FloatType {
271 self.duration.quarter_length()
272 }
273
274 pub fn full_name(&self) -> String {
277 format!("{} Rest", self.duration.full_name())
278 }
279
280 pub fn lyrics(&self) -> &[Lyric] {
282 &self.lyrics
283 }
284
285 pub fn lyrics_mut(&mut self) -> &mut Vec<Lyric> {
287 &mut self.lyrics
288 }
289
290 pub fn lyric(&self) -> Option<String> {
292 verses::joined(&self.lyrics)
293 }
294
295 pub fn set_lyric(&mut self, lyric: Option<&str>) {
298 verses::set(&mut self.lyrics, lyric);
299 }
300
301 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 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}