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, 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 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 pub fn full_measure(&self) -> Option<bool> {
65 self.full_measure
66 }
67
68 pub fn set_full_measure(&mut self, full_measure: Option<bool>) {
70 self.full_measure = full_measure;
71 }
72
73 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 pub fn tie(&self) -> Option<&crate::notation::Tie> {
84 self.tie.as_ref()
85 }
86
87 pub fn set_tie(&mut self, tie: Option<crate::notation::Tie>) {
89 self.tie = tie;
90 }
91
92 pub fn size(&self) -> Option<crate::notation::NoteSize> {
95 self.size
96 }
97
98 pub fn set_size(&mut self, size: Option<crate::notation::NoteSize>) {
100 self.size = size;
101 }
102
103 pub fn step_shift(&self) -> IntegerType {
107 self.step_shift
108 }
109
110 pub fn set_step_shift(&mut self, shift: IntegerType) {
112 self.step_shift = shift;
113 }
114
115 pub fn expressions(&self) -> &[Expression] {
118 &self.expressions
119 }
120
121 pub fn expressions_mut(&mut self) -> &mut Vec<Expression> {
123 &mut self.expressions
124 }
125
126 pub fn articulations(&self) -> &[Articulation] {
128 &self.articulations
129 }
130
131 pub fn articulations_mut(&mut self) -> &mut Vec<Articulation> {
133 &mut self.articulations
134 }
135
136 pub fn hidden(&self) -> bool {
140 self.hidden
141 }
142
143 pub fn set_hidden(&mut self, hidden: bool) {
145 self.hidden = hidden;
146 }
147
148 pub fn from_quarter_length(quarter_length: crate::FloatType) -> crate::Result<Self> {
150 Ok(Self::new(Duration::new(quarter_length)?))
151 }
152
153 pub fn duration(&self) -> &Duration {
155 &self.duration
156 }
157
158 pub fn set_duration(&mut self, duration: Duration) {
160 self.duration = duration;
161 }
162
163 pub fn quarter_length(&self) -> crate::FloatType {
165 self.duration.quarter_length()
166 }
167
168 pub fn full_name(&self) -> String {
171 format!("{} Rest", self.duration.full_name())
172 }
173
174 pub fn lyrics(&self) -> &[Lyric] {
176 &self.lyrics
177 }
178
179 pub fn lyrics_mut(&mut self) -> &mut Vec<Lyric> {
181 &mut self.lyrics
182 }
183
184 pub fn lyric(&self) -> Option<String> {
186 verses::joined(&self.lyrics)
187 }
188
189 pub fn set_lyric(&mut self, lyric: Option<&str>) {
192 verses::set(&mut self.lyrics, lyric);
193 }
194
195 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 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}