use std::fmt::Display;
use write_fonts::{read::ReadError, BuilderError};
use crate::{parse::SourceLoadError, DiagnosticSet};
#[derive(Clone, Debug, thiserror::Error)]
pub enum UfoGlyphOrderError {
#[error("No public.glyphOrder key in lib.plist")]
KeyNotSet,
#[error("public.glyphOrder exists, but is not an array of strings")]
Malformed,
}
#[derive(Clone, Debug, thiserror::Error)]
pub enum FontGlyphOrderError {
#[error("Failed to read font data: '{0}'")]
ReadError(
#[from]
#[source]
ReadError,
),
#[error("The post table exists, but did not include all glyph names")]
MissingNames,
}
#[derive(Clone, Debug, thiserror::Error)]
pub enum GlyphOrderError {
#[error("Invalid name '{name}' in glyph order")]
#[allow(missing_docs)]
NameError { name: String },
#[error("The first glyph must be '.notdef'")]
MissingNotDef,
}
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum CompilerError {
#[error(transparent)]
SourceLoad(#[from] SourceLoadError),
#[error("FEA parsing failed with {} errors", .0.messages.len())]
ParseFail(DiagnosticSet),
#[error("FEA validation failed with {} errors", .0.messages.len())]
ValidationFail(DiagnosticSet),
#[error("FEA compilation failed with {} errors", .0.messages.len())]
CompilationFail(DiagnosticSet),
#[error(transparent)]
WriteFail(#[from] BuilderError),
}
impl CompilerError {
pub fn display_verbose(&self) -> impl Display + '_ {
struct Verbose<'a>(&'a CompilerError);
impl std::fmt::Display for Verbose<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.0)?;
if let Some(diagnostics) = self.0.diagnostics() {
write!(f, "\n{}", diagnostics.display())?;
}
Ok(())
}
}
Verbose(self)
}
pub fn diagnostics(&self) -> Option<&DiagnosticSet> {
match self {
CompilerError::ParseFail(x)
| CompilerError::ValidationFail(x)
| CompilerError::CompilationFail(x) => Some(x),
_ => None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn assert_compiler_error_is_send() {
fn send_me_baby<T: Send>() {}
send_me_baby::<CompilerError>();
}
}