diff --git a/fea-rs/src/bin/compile.rs b/fea-rs/src/bin/compile.rs index a970ad02..f5c1db87 100644 --- a/fea-rs/src/bin/compile.rs +++ b/fea-rs/src/bin/compile.rs @@ -6,7 +6,7 @@ use clap::Parser; use fea_rs::{ compile::{ self, - error::{FontGlyphOrderError, GlyphOrderError, UfoGlyphOrderError}, + error::{CompilerError, FontGlyphOrderError, GlyphOrderError, UfoGlyphOrderError}, Compiler, MockVariationInfo, NopFeatureProvider, Opts, }, GlyphMap, @@ -80,8 +80,8 @@ enum Error { MissingGlyphOrder, #[error("Error parsing axis info: L{line}, '{message}'")] BadAxisInfo { line: usize, message: String }, - #[error("{0}")] - CompileFail(#[from] compile::error::CompilerError), + #[error("{}", .0.display_verbose())] + CompileFail(#[from] CompilerError), } /// Compile FEA files diff --git a/fea-rs/src/compile/error.rs b/fea-rs/src/compile/error.rs index 57761eac..e445248a 100644 --- a/fea-rs/src/compile/error.rs +++ b/fea-rs/src/compile/error.rs @@ -1,5 +1,7 @@ //! Error types related to compilation +use std::fmt::Display; + use write_fonts::{read::ReadError, BuilderError}; use crate::{parse::SourceLoadError, DiagnosticSet}; @@ -58,6 +60,26 @@ pub enum CompilerError { WriteFail(#[from] BuilderError), } +impl CompilerError { + /// Return a `Display` type that reports the location and nature of syntax errors + 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)?; + let diagnostic = match self.0 { + CompilerError::ParseFail(x) + | CompilerError::ValidationFail(x) + | CompilerError::CompilationFail(x) => x, + _ => return Ok(()), + }; + write!(f, "\n{}", diagnostic.display()) + } + } + Verbose(self) + } +} + #[cfg(test)] mod tests { use super::*;