musicxml/elements/
backup.rs

1use super::{Duration, Footnote, Level};
2use alloc::{string::String, vec::Vec};
3use musicxml_internal::*;
4use musicxml_macros::*;
5
6/// Contents of the [Backup] element.
7#[derive(Debug, PartialEq, Eq, ContentDeserialize, ContentSerialize)]
8pub struct BackupContents {
9  /// The [Duration] element specifies the number of divisions to move back.
10  pub duration: Duration,
11  /// The [Footnote] element specifies editorial information or lyrics content.
12  pub footnote: Option<Footnote>,
13  /// The [Level] element specifies the editorial level of a score or part.
14  pub level: Option<Level>,
15}
16
17/// The [Backup] and [Forward][super::Forward] elements are required to coordinate multiple voices in one part, including music on multiple staves.
18///
19/// ![Backup](https://hedgetechllc.github.io/musicxml/musicxml/elements/backup.png)
20///
21/// The [Backup] element is generally used to move between voices and staves. Thus it does not include [Voice][super::Voice] or [Staff][super::Staff] elements.
22/// Duration values should always be positive, and should not cross measure boundaries or mid-measure changes in the [Divisions][super::Divisions] value.
23#[derive(Debug, PartialEq, Eq, ElementDeserialize, ElementSerialize)]
24pub struct Backup {
25  /// Element-specific attributes
26  pub attributes: (),
27  #[flatten]
28  /// Element-specific content
29  pub content: BackupContents,
30}
31
32#[cfg(test)]
33mod backup_tests {
34  use super::*;
35  use crate::parser::parse_from_xml_str;
36  use crate::{
37    datatypes::PositiveDivisions,
38    elements::{FootnoteAttributes, LevelAttributes},
39  };
40
41  #[test]
42  fn deserialize_valid1() {
43    let result = parse_from_xml_str::<Backup>(
44      "
45    <backup>
46      <duration>2</duration>
47      <footnote>Footnote</footnote>
48      <level>Level</level>
49    </backup>",
50    );
51    assert!(result.is_ok());
52    assert_eq!(
53      result.unwrap(),
54      Backup {
55        attributes: (),
56        content: BackupContents {
57          duration: Duration {
58            attributes: (),
59            content: PositiveDivisions(2)
60          },
61          footnote: Some(Footnote {
62            attributes: FootnoteAttributes::default(),
63            content: String::from("Footnote")
64          }),
65          level: Some(Level {
66            attributes: LevelAttributes::default(),
67            content: String::from("Level")
68          }),
69        }
70      }
71    );
72  }
73}