#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum AbcSpecVersion {
#[default]
V21,
V22Draft,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum ParseMode {
#[default]
Strict,
Loose,
Recover,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct DiagnosticOptions {
pub suppress_croma_carrier_warnings: bool,
}
impl DiagnosticOptions {
pub fn suppress_croma_carrier_warnings(mut self) -> Self {
self.suppress_croma_carrier_warnings = true;
self
}
pub(crate) fn should_emit_croma_carrier_warning(self, name: &str) -> bool {
!self.suppress_croma_carrier_warnings
|| !(is_croma_carrier_name(name) || is_croma_managed_midi_name(name))
}
}
pub fn is_croma_carrier_name(name: &str) -> bool {
let name = name.trim_start();
name.get(.."croma-".len())
.is_some_and(|prefix| prefix.eq_ignore_ascii_case("croma-"))
|| is_compact_croma_carrier_name(name)
}
fn is_compact_croma_carrier_name(name: &str) -> bool {
name.split_once(char::is_whitespace)
.is_some_and(|(head, code)| {
head.eq_ignore_ascii_case(crate::lower::carrier::COMPACT_NAMESPACE)
&& !code.trim().is_empty()
})
}
fn is_croma_managed_midi_name(name: &str) -> bool {
name.trim_start().eq_ignore_ascii_case("MIDI")
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct ParseOptions {
pub spec: AbcSpecVersion,
pub mode: ParseMode,
pub diagnostics: DiagnosticOptions,
}
impl ParseOptions {
pub fn new(spec: AbcSpecVersion, mode: ParseMode) -> Self {
Self {
spec,
mode,
diagnostics: DiagnosticOptions::default(),
}
}
pub fn suppress_croma_carrier_warnings(mut self) -> Self {
self.diagnostics = self.diagnostics.suppress_croma_carrier_warnings();
self
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct ExportOptions {
pub spec: AbcSpecVersion,
pub parse_mode: ParseMode,
pub diagnostics: DiagnosticOptions,
pub write: MusicXmlWriteOptions,
}
impl ExportOptions {
pub fn parse_options(self) -> ParseOptions {
ParseOptions {
spec: self.spec,
mode: self.parse_mode,
diagnostics: self.diagnostics,
}
}
pub fn suppress_croma_carrier_warnings(mut self) -> Self {
self.diagnostics = self.diagnostics.suppress_croma_carrier_warnings();
self
}
pub fn engrave(mut self) -> Self {
self.write = MusicXmlWriteOptions::engrave();
self
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct MusicXmlWriteOptions {
pub beams: bool,
pub tuplet_display: TupletDisplay,
pub stems: bool,
pub rest_placement: bool,
pub slur_placement: bool,
pub tie_orientation: bool,
}
impl MusicXmlWriteOptions {
pub fn engrave() -> Self {
Self {
beams: true,
tuplet_display: TupletDisplay::EngravingDefault,
stems: true,
rest_placement: true,
slur_placement: true,
tie_orientation: true,
}
}
pub fn any_enabled(self) -> bool {
self.beams
|| self.stems
|| self.rest_placement
|| self.slur_placement
|| self.tie_orientation
|| self.tuplet_display != TupletDisplay::AsEncoded
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum TupletDisplay {
#[default]
AsEncoded,
EngravingDefault,
}
impl From<ExportOptions> for ParseOptions {
fn from(options: ExportOptions) -> Self {
options.parse_options()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct LowerOptions;
#[cfg(test)]
#[path = "options_tests.rs"]
mod tests;