1use std::fmt;
7
8#[derive(Debug)]
10pub enum FormeError {
11 ParseError {
13 source: serde_json::Error,
14 hint: String,
15 },
16 FontError(String),
18 RenderError(String),
20 TemplateError(String),
22}
23
24impl fmt::Display for FormeError {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 match self {
27 FormeError::ParseError { source, hint } => {
28 write!(f, "Failed to parse document: {}", source)?;
29 if !hint.is_empty() {
30 write!(f, "\n Hint: {}", hint)?;
31 }
32 Ok(())
33 }
34 FormeError::FontError(msg) => write!(f, "Font error: {}", msg),
35 FormeError::RenderError(msg) => write!(f, "Render error: {}", msg),
36 FormeError::TemplateError(msg) => write!(f, "Template error: {}", msg),
37 }
38 }
39}
40
41impl std::error::Error for FormeError {
42 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
43 match self {
44 FormeError::ParseError { source, .. } => Some(source),
45 _ => None,
46 }
47 }
48}
49
50impl From<serde_json::Error> for FormeError {
51 fn from(e: serde_json::Error) -> Self {
52 let hint = match e.classify() {
53 serde_json::error::Category::Syntax => {
54 "Check for trailing commas, missing quotes, or unescaped characters.".to_string()
55 }
56 serde_json::error::Category::Data => {
57 "The JSON is valid but doesn't match the Forme document schema. Check field names and types.".to_string()
58 }
59 serde_json::error::Category::Eof => {
60 "Unexpected end of input — is the JSON truncated?".to_string()
61 }
62 serde_json::error::Category::Io => String::new(),
63 };
64 FormeError::ParseError { source: e, hint }
65 }
66}