use super::{BeatRepeat, MeasureRepeat, MultipleRest, Slash};
use crate::datatypes::{Color, FontFamily, FontSize, FontStyle, FontWeight, Id, StaffNumber};
use alloc::{string::String, vec::Vec};
use musicxml_internal::*;
use musicxml_macros::*;
#[derive(Debug, Default, PartialEq, Eq, AttributeDeserialize, AttributeSerialize)]
pub struct MeasureStyleAttributes {
pub color: Option<Color>,
pub font_family: Option<FontFamily>,
pub font_size: Option<FontSize>,
pub font_style: Option<FontStyle>,
pub font_weight: Option<FontWeight>,
pub id: Option<Id>,
pub number: Option<StaffNumber>,
}
#[derive(Debug, PartialEq, Eq)]
pub enum MeasureStyleContents {
MultipleRest(MultipleRest),
MeasureRepeat(MeasureRepeat),
BeatRepeat(BeatRepeat),
Slash(Slash),
}
#[derive(Debug, PartialEq, Eq)]
pub struct MeasureStyle {
pub attributes: MeasureStyleAttributes,
pub content: MeasureStyleContents,
}
impl ElementDeserializer for MeasureStyle {
fn deserialize(element: &XmlElement) -> Result<Self, String> {
Ok(MeasureStyle {
attributes: MeasureStyleAttributes::deserialize(&element.attributes)?,
content: match element
.elements
.first()
.ok_or("Missing required content elements in <measure-style>")?
{
el if el.name == "multiple-rest" => MeasureStyleContents::MultipleRest(MultipleRest::deserialize(el)?),
el if el.name == "measure-repeat" => MeasureStyleContents::MeasureRepeat(MeasureRepeat::deserialize(el)?),
el if el.name == "beat-repeat" => MeasureStyleContents::BeatRepeat(BeatRepeat::deserialize(el)?),
el if el.name == "slash" => MeasureStyleContents::Slash(Slash::deserialize(el)?),
el => return Err(format!("Invalid <measure-style> element name: {}", el.name)),
},
})
}
}
impl ElementSerializer for MeasureStyle {
fn serialize(element: &Self) -> XmlElement {
XmlElement {
name: String::from("measure-style"),
attributes: MeasureStyleAttributes::serialize(&element.attributes),
elements: vec![match &element.content {
MeasureStyleContents::MultipleRest(content) => MultipleRest::serialize(content),
MeasureStyleContents::MeasureRepeat(content) => MeasureRepeat::serialize(content),
MeasureStyleContents::BeatRepeat(content) => BeatRepeat::serialize(content),
MeasureStyleContents::Slash(content) => Slash::serialize(content),
}],
text: String::new(),
}
}
}