use sim_kernel::{Diagnostic, Severity, SourceId, Span};
use sim_lib_music_core::{MusicError, Score};
use thiserror::Error;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct NotationReport<T> {
pub value: T,
pub diagnostics: Vec<Diagnostic>,
}
#[derive(Debug, Error, Clone, PartialEq, Eq)]
pub enum NotationError {
#[error("unsupported duration {0}")]
UnsupportedDuration(String),
#[error("unsupported music object {0}")]
UnsupportedMusicObject(&'static str),
#[error("invalid key signature {0}")]
InvalidKey(String),
#[error("unsupported lilypond syntax")]
UnsupportedSyntax {
diagnostics: Vec<Diagnostic>,
},
#[error(transparent)]
Music(#[from] MusicError),
}
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
pub struct NotationCodec;
impl NotationCodec {
pub fn export_lilypond_report(
&self,
score: &Score,
) -> Result<NotationReport<String>, NotationError> {
crate::export::export_lilypond_report(score)
}
pub fn export_lilypond(&self, score: &Score) -> Result<String, NotationError> {
crate::export::export_lilypond(score)
}
pub fn import_lilypond_report(
&self,
source: &str,
) -> Result<NotationReport<Score>, NotationError> {
crate::import::import_lilypond_report(source)
}
pub fn import_lilypond(&self, source: &str) -> Result<Score, NotationError> {
crate::import::import_lilypond(source)
}
}
pub(crate) fn error_at(message: impl Into<String>, span: Span) -> NotationError {
NotationError::UnsupportedSyntax {
diagnostics: vec![Diagnostic {
severity: Severity::Error,
message: message.into(),
source: Some(SourceId("notation:lilypond".to_owned())),
span: Some(span),
code: None,
related: Vec::new(),
}],
}
}