markup_fmt/
error.rs

1use std::{borrow::Cow, error::Error, fmt};
2
3#[derive(Clone, Debug)]
4/// Syntax error when parsing tags, not `<script>` or `<style>` tag.
5pub struct SyntaxError {
6    pub kind: SyntaxErrorKind,
7    pub pos: usize,
8    pub line: usize,
9    pub column: usize,
10}
11
12#[derive(Clone, Debug)]
13pub enum SyntaxErrorKind {
14    ExpectAngularBlock(&'static str),
15    ExpectAngularLet,
16    ExpectAngularSwitch,
17    ExpectAstroAttr,
18    ExpectAstroExpr,
19    ExpectAttrName,
20    ExpectAttrValue,
21    ExpectCdata,
22    ExpectChar(char),
23    ExpectCloseTag {
24        tag_name: String,
25        line: usize,
26        column: usize,
27    },
28    ExpectComment,
29    ExpectDoctype,
30    ExpectElement,
31    ExpectFrontMatter,
32    ExpectIdentifier,
33    ExpectJinjaBlockEnd,
34    ExpectJinjaTag,
35    ExpectKeyword(&'static str),
36    ExpectMustacheInterpolation,
37    ExpectSelfCloseTag,
38    ExpectSvelteAttachment,
39    ExpectSvelteAtTag,
40    ExpectSvelteAttr,
41    ExpectSvelteAwaitBlock,
42    ExpectSvelteBlockEnd,
43    ExpectSvelteCatchBlock,
44    ExpectSvelteEachBlock,
45    ExpectSvelteElseIfBlock,
46    ExpectSvelteIfBlock,
47    ExpectSvelteInterpolation,
48    ExpectSvelteKeyBlock,
49    ExpectSvelteSnippetBlock,
50    ExpectSvelteThenBlock,
51    ExpectTagName,
52    ExpectTextNode,
53    ExpectVentoBlockEnd,
54    ExpectVueDirective,
55    ExpectXmlDecl,
56}
57
58impl fmt::Display for SyntaxErrorKind {
59    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60        let reason: Cow<_> = match self {
61            SyntaxErrorKind::ExpectAngularBlock(keyword) => {
62                format!("expected Angular `@{keyword}` block").into()
63            }
64            SyntaxErrorKind::ExpectAngularLet => "expected Angular `@let`".into(),
65            SyntaxErrorKind::ExpectAngularSwitch => "expected Angular `@switch`".into(),
66            SyntaxErrorKind::ExpectAstroAttr => "expected Astro attribute".into(),
67            SyntaxErrorKind::ExpectAstroExpr => "expected Astro expression".into(),
68            SyntaxErrorKind::ExpectAttrName => "expected attribute name".into(),
69            SyntaxErrorKind::ExpectAttrValue => "expected attribute value".into(),
70            SyntaxErrorKind::ExpectCdata => "expected CDATA section".into(),
71            SyntaxErrorKind::ExpectChar(c) => format!("expected char '{c}'").into(),
72            SyntaxErrorKind::ExpectCloseTag {
73                tag_name,
74                line,
75                column,
76            } => format!(
77                "expected close tag for opening tag <{tag_name}> from line {line}, column {column}"
78            )
79            .into(),
80            SyntaxErrorKind::ExpectComment => "expected comment".into(),
81            SyntaxErrorKind::ExpectDoctype => "expected HTML doctype".into(),
82            SyntaxErrorKind::ExpectElement => "expected element".into(),
83            SyntaxErrorKind::ExpectFrontMatter => "expected front matter".into(),
84            SyntaxErrorKind::ExpectIdentifier => "expected identifier".into(),
85            SyntaxErrorKind::ExpectJinjaBlockEnd => "expected Jinja block end".into(),
86            SyntaxErrorKind::ExpectJinjaTag => "expected Jinja tag".into(),
87            SyntaxErrorKind::ExpectKeyword(keyword) => {
88                format!("expected keyword '{keyword}'").into()
89            }
90            SyntaxErrorKind::ExpectMustacheInterpolation => {
91                "expected mustache-like interpolation".into()
92            }
93            SyntaxErrorKind::ExpectSelfCloseTag => "expected self close tag".into(),
94            SyntaxErrorKind::ExpectSvelteAttachment => "expected Svelte attachment".into(),
95            SyntaxErrorKind::ExpectSvelteAtTag => "expected Svelte `{@` tag".into(),
96            SyntaxErrorKind::ExpectSvelteAttr => "expected Svelte attribute".into(),
97            SyntaxErrorKind::ExpectSvelteAwaitBlock => "expected Svelte await block".into(),
98            SyntaxErrorKind::ExpectSvelteBlockEnd => "expected end of Svelte block".into(),
99            SyntaxErrorKind::ExpectSvelteCatchBlock => "expected Svelte catch block".into(),
100            SyntaxErrorKind::ExpectSvelteEachBlock => "expected Svelte each block".into(),
101            SyntaxErrorKind::ExpectSvelteElseIfBlock => "expected Svelte else if block".into(),
102            SyntaxErrorKind::ExpectSvelteIfBlock => "expected Svelte if block".into(),
103            SyntaxErrorKind::ExpectSvelteInterpolation => "expected Svelte interpolation".into(),
104            SyntaxErrorKind::ExpectSvelteKeyBlock => "expected Svelte key block".into(),
105            SyntaxErrorKind::ExpectSvelteSnippetBlock => "expected Svelte snippet block".into(),
106            SyntaxErrorKind::ExpectSvelteThenBlock => "expected Svelte then block".into(),
107            SyntaxErrorKind::ExpectTagName => "expected tag name".into(),
108            SyntaxErrorKind::ExpectTextNode => "expected text node".into(),
109            SyntaxErrorKind::ExpectVentoBlockEnd => "expected Vento block end".into(),
110            SyntaxErrorKind::ExpectVueDirective => "expected Vue directive".into(),
111            SyntaxErrorKind::ExpectXmlDecl => "expected XML declaration".into(),
112        };
113
114        write!(f, "{reason}")
115    }
116}
117
118impl fmt::Display for SyntaxError {
119    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
120        write!(
121            f,
122            "syntax error '{}' at line {}, column {}",
123            self.kind, self.line, self.column
124        )
125    }
126}
127
128impl Error for SyntaxError {}
129
130#[derive(Debug)]
131/// The error type for markup_fmt.
132pub enum FormatError<E> {
133    /// Syntax error when parsing tags.
134    Syntax(SyntaxError),
135    /// Error from external formatter, for example,
136    /// there're errors when formatting the `<script>` or `<style>` tag.
137    External(Vec<E>),
138}
139
140impl<E> fmt::Display for FormatError<E>
141where
142    E: fmt::Display,
143{
144    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
145        match self {
146            FormatError::Syntax(e) => e.fmt(f),
147            FormatError::External(errors) => {
148                writeln!(f, "failed to format code with external formatter:")?;
149                for error in errors {
150                    writeln!(f, "{error}")?;
151                }
152                Ok(())
153            }
154        }
155    }
156}
157
158impl<E> Error for FormatError<E> where E: Error {}