1use std::fmt::Display;
4
5use write_fonts::{BuilderError, read::ReadError};
6
7use crate::{DiagnosticSet, parse::SourceLoadError};
8
9#[derive(Clone, Debug, thiserror::Error)]
11pub enum UfoGlyphOrderError {
12 #[error("No public.glyphOrder key in lib.plist")]
14 KeyNotSet,
15 #[error("public.glyphOrder exists, but is not an array of strings")]
17 Malformed,
18}
19
20#[derive(Clone, Debug, thiserror::Error)]
22pub enum FontGlyphOrderError {
23 #[error("Failed to read font data: '{0}'")]
25 ReadError(
26 #[from]
27 #[source]
28 ReadError,
29 ),
30 #[error("The post table exists, but did not include all glyph names")]
32 MissingNames,
33}
34
35#[derive(Clone, Debug, thiserror::Error)]
37pub enum GlyphOrderError {
38 #[error("Invalid name '{name}' in glyph order")]
40 #[allow(missing_docs)]
41 NameError { name: String },
42 #[error("The first glyph must be '.notdef'")]
44 MissingNotDef,
45}
46
47#[derive(Debug, thiserror::Error)]
49#[allow(missing_docs)]
50pub enum CompilerError {
51 #[error(transparent)]
52 SourceLoad(#[from] SourceLoadError),
53 #[error("FEA parsing failed with {} errors", .0.messages.len())]
54 ParseFail(DiagnosticSet),
55 #[error("FEA validation failed with {} errors", .0.messages.len())]
56 ValidationFail(DiagnosticSet),
57 #[error("FEA compilation failed with {} errors", .0.messages.len())]
58 CompilationFail(DiagnosticSet),
59 #[error(transparent)]
60 WriteFail(#[from] BuilderError),
61}
62
63impl CompilerError {
64 pub fn display_verbose(&self) -> impl Display + '_ {
66 struct Verbose<'a>(&'a CompilerError);
67 impl std::fmt::Display for Verbose<'_> {
68 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
69 write!(f, "{}", self.0)?;
70 if let Some(diagnostics) = self.0.diagnostics() {
71 write!(f, "\n{}", diagnostics.display())?;
72 }
73 Ok(())
74 }
75 }
76 Verbose(self)
77 }
78
79 pub fn diagnostics(&self) -> Option<&DiagnosticSet> {
81 match self {
82 CompilerError::ParseFail(x)
83 | CompilerError::ValidationFail(x)
84 | CompilerError::CompilationFail(x) => Some(x),
85 _ => None,
86 }
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 #[test]
96 fn assert_compiler_error_is_send() {
97 fn send_me_baby<T: Send>() {}
98 send_me_baby::<CompilerError>();
99 }
100}