1use crate::duration::Duration;
2
3#[derive(Clone, Debug, PartialEq)]
5#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6#[must_use]
7pub struct Rest {
8 duration: Duration,
9}
10
11impl Rest {
12 pub fn new(duration: Duration) -> Self {
14 Self { duration }
15 }
16
17 pub fn from_quarter_length(quarter_length: crate::FloatType) -> crate::Result<Self> {
19 Ok(Self::new(Duration::new(quarter_length)?))
20 }
21
22 pub fn duration(&self) -> &Duration {
24 &self.duration
25 }
26
27 pub fn set_duration(&mut self, duration: Duration) {
29 self.duration = duration;
30 }
31
32 pub fn quarter_length(&self) -> crate::FloatType {
34 self.duration.quarter_length()
35 }
36
37 pub fn full_name(&self) -> String {
40 format!("{} Rest", self.duration.full_name())
41 }
42}
43
44impl Default for Rest {
45 fn default() -> Self {
46 Self::new(Duration::default())
47 }
48}
49
50impl From<Duration> for Rest {
51 fn from(value: Duration) -> Self {
52 Self::new(value)
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59
60 #[test]
61 fn rest_has_duration() {
62 let rest = Rest::from_quarter_length(2.0).unwrap();
63 assert_eq!(rest.quarter_length(), 2.0);
64 }
65
66 #[test]
67 fn a_rest_is_named_by_its_length() {
68 assert_eq!(
69 Rest::from_quarter_length(1.5).unwrap().full_name(),
70 "Dotted Quarter Rest"
71 );
72 assert_eq!(Rest::new(Duration::whole()).full_name(), "Whole Rest");
73 }
74
75 #[test]
76 fn rest_supports_default_from_and_updates() {
77 let mut rest = Rest::default();
78 assert_eq!(rest.quarter_length(), 1.0);
79
80 rest.set_duration(Duration::whole());
81 assert_eq!(rest.duration(), &Duration::whole());
82
83 let half_rest = Rest::from(Duration::half());
84 assert_eq!(half_rest.quarter_length(), 2.0);
85 assert!(Rest::from_quarter_length(crate::FloatType::NAN).is_err());
86 }
87}