bracket/error/
syntax.rs

1//! Errors generated when compiling templates.
2use std::fmt;
3use thiserror::Error;
4
5/// Errors generated when compiling a template.
6#[derive(Error, Eq, PartialEq)]
7pub enum SyntaxError {
8    /// Error when an identifier is expected.
9    #[error("Syntax error, expecting identifier")]
10    ExpectedIdentifier(String),
11
12    /// Error when a path is expected.
13    #[error("Syntax error, expecting path")]
14    ExpectedPath(String),
15
16    /// Error if a block name is not a simple identifier.
17    #[error("Syntax error, block name must be an identifier")]
18    BlockName(String),
19
20    /// Error when a newline is enccountered in a raw literal.
21    #[error("Syntax error, new lines in raw literals must be escaped (\\n)")]
22    LiteralNewline(String),
23
24    /// Error when the partial operator is not the first token in a call statement.
25    #[error("Syntax error, partial operator (>) must come first")]
26    PartialPosition(String),
27
28    /// Error when a sub-expression is closed by no sub-expression is open.
29    #[error(
30        "Syntax error, got close sub-expression but no sub-expression is open"
31    )]
32    SubExprNotOpen(String),
33
34    /// Error when a sub-expression attempts to use a sub-expression for it's target.
35    ///
36    /// Currently sub-expressions for the target are only supported when evaluating
37    /// partials.
38    #[error(
39        "Syntax error, sub-expression must use an identifier for the target"
40    )]
41    SubExprTargetNotAllowed(String),
42
43    /// Error when a path delimiter is encountered in an invalid position.
44    #[error("Syntax error, path delimiter (.) not allowed here")]
45    PathDelimiterNotAllowed(String),
46
47    /// Error when the `else` keyword is encountered in an invalid position.
48    #[error("Syntax error, 'else' keyword is not allowed here")]
49    ElseNotAllowed(String),
50
51    /// Error when the `this` keywords is not at the start of a path.
52    #[error(
53        "Syntax error, explicit this reference must be at the start of a path"
54    )]
55    UnexpectedPathExplicitThis(String),
56
57    /// Error when a parent path reference (../) is not at the start of a path.
58    #[error("Syntax error, parent scopes must be at the start of a path")]
59    UnexpectedPathParent(String),
60
61    /// Error when a local identifier is not at the start of a path.
62    #[error(
63        "Syntax error, local scope identifiers must be at the start of a path"
64    )]
65    UnexpectedPathLocal(String),
66
67    /// Error when an identifier is expected but a path delimiter was encountered.
68    #[error("Syntax error, expected identifier but got path delimiter")]
69    UnexpectedPathDelimiter(String),
70
71    /// Error when parent scope references and local identifiers are combined illegally.
72    #[error("Syntax error, parent scopes and local identifiers are mutually exclusive")]
73    UnexpectedPathParentWithLocal(String),
74
75    /// Error attempting to mix parent scope references and explicit this.
76    #[error(
77        "Syntax error, parent scopes and explicit this are mutually exclusive"
78    )]
79    UnexpectedPathParentWithExplicit(String),
80
81    /// Error when a path delimiter is expected.
82    #[error("Syntax error, expected path delimiter (.)")]
83    ExpectedPathDelimiter(String),
84
85    /// Error when a sub-expression was not terminated.
86    #[error("Syntax error, sub-expression not terminated")]
87    OpenSubExpression(String),
88
89    /// Error when a closing tag name does not match the opening name.
90    #[error("Syntax error, closing name does not match")]
91    TagNameMismatch(String),
92
93    /// Error when an end tag is encountered but no block is open.
94    #[error("Syntax error, got a closing tag but no block is open")]
95    BlockNotOpen(String),
96
97    /// Error when a sub-expression is not terminated.
98    #[error("Syntax error, sub-expression was not terminated")]
99    SubExpressionNotTerminated(String),
100    /// Erro when a link is not terminated.
101    #[error("Syntax error, link was not terminated")]
102    LinkNotTerminated(String),
103
104    /// Error when the opening tag for a raw block is not terminated.
105    #[error("Syntax error, raw block open tag was not terminated")]
106    RawBlockOpenNotTerminated(String),
107
108    /// Error when a raw block is not terminated.
109    #[error("Syntax error, raw block was not terminated")]
110    RawBlockNotTerminated(String),
111    /// Error when a raw comment is not terminated.
112    #[error("Syntax error, raw comment was not terminated")]
113    RawCommentNotTerminated(String),
114    /// Error when a raw statement is not terminated.
115    #[error("Syntax error, raw statement was not terminated")]
116    RawStatementNotTerminated(String),
117    /// Error when a comment is not terminated.
118    #[error("Syntax error, comment was not terminated")]
119    CommentNotTerminated(String),
120
121    /// Error attempting to use a sub-expression outside of a partial target context.
122    #[error("Syntax error, block target sub expressions are only supported for partials")]
123    BlockTargetSubExpr(String),
124    /// Error when an empty path is encountered.
125    #[error("Syntax error, path is empty")]
126    EmptyPath(String),
127    /// Error if we could not identify the type of a path component (internal error).
128    #[error("Syntax error, path component type could not be identified")]
129    ComponentType(String),
130    /// Error attempting to combine partials with conditionals.
131    #[error("Syntax error, partials and conditionals may not be combined")]
132    MixedPartialConditional(String),
133
134    /// Invalid token error (internal error).
135    #[error("Syntax error, unexpected error token for context '{0}'")]
136    TokenError(String, String),
137    /// Invalid token error (internal error).
138    #[error("Syntax error, expecting path or sub-expression for call target")]
139    TokenCallTarget(String),
140    /// Invalid token error (internal error).
141    #[error("Syntax error, expecting JSON literal token")]
142    TokenJsonLiteral(String),
143    /// Invalid token error (internal error).
144    #[error("Syntax error, expecting parameter token")]
145    TokenParameter(String),
146    /// Invalid token error (internal error).
147    #[error("Syntax error, expecting key/value token")]
148    TokenHashKeyValue(String),
149    /// Invalid token error (internal error).
150    #[error("Syntax error, expecting raw literal token")]
151    TokenRawLiteral(String),
152    /// Invalid token error (internal error).
153    #[error("Syntax error, unexpected token parsing quoted literal (\"\")")]
154    TokenDoubleQuoteLiteral(String),
155    /// Invalid token error (internal error).
156    #[error("Syntax error, unexpected token parsing quoted literal ('')")]
157    TokenSingleQuoteLiteral(String),
158    /// Invalid token error (internal error).
159    #[error("Syntax error, unexpected token parsing quoted literal ([])")]
160    TokenArrayLiteral(String),
161    /// Invalid token error (internal error).
162    #[error("Syntax error, unexpected token parsing link")]
163    TokenLink(String),
164    /// Invalid token error (internal error).
165    #[error("Syntax error, unexpected token parsing path")]
166    TokenParameterPath(String),
167    /// Invalid token error (internal error).
168    #[error("Syntax error, unexpected token, expecting end of raw block")]
169    TokenEndRawBlock(String),
170}
171
172impl fmt::Debug for SyntaxError {
173    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174        write!(f, "{}\n", self.to_string())?;
175        match *self {
176            Self::ExpectedIdentifier(ref source)
177            | Self::ExpectedPath(ref source)
178            | Self::BlockName(ref source)
179            | Self::LiteralNewline(ref source)
180            | Self::PartialPosition(ref source)
181            | Self::SubExprNotOpen(ref source)
182            | Self::SubExprTargetNotAllowed(ref source)
183            | Self::PathDelimiterNotAllowed(ref source)
184            | Self::ElseNotAllowed(ref source)
185            | Self::UnexpectedPathExplicitThis(ref source)
186            | Self::UnexpectedPathParent(ref source)
187            | Self::UnexpectedPathLocal(ref source)
188            | Self::UnexpectedPathDelimiter(ref source)
189            | Self::UnexpectedPathParentWithLocal(ref source)
190            | Self::UnexpectedPathParentWithExplicit(ref source)
191            | Self::ExpectedPathDelimiter(ref source)
192            | Self::OpenSubExpression(ref source)
193            | Self::TagNameMismatch(ref source)
194            | Self::SubExpressionNotTerminated(ref source)
195            | Self::LinkNotTerminated(ref source)
196            | Self::RawBlockNotTerminated(ref source)
197            | Self::RawCommentNotTerminated(ref source)
198            | Self::RawStatementNotTerminated(ref source)
199            | Self::CommentNotTerminated(ref source)
200            | Self::BlockTargetSubExpr(ref source)
201            | Self::EmptyPath(ref source)
202            | Self::ComponentType(ref source)
203            | Self::MixedPartialConditional(ref source)
204            | Self::RawBlockOpenNotTerminated(ref source)
205            | Self::TokenError(_, ref source)
206            | Self::TokenCallTarget(ref source)
207            | Self::TokenJsonLiteral(ref source)
208            | Self::TokenParameter(ref source)
209            | Self::TokenHashKeyValue(ref source)
210            | Self::TokenRawLiteral(ref source)
211            | Self::TokenDoubleQuoteLiteral(ref source)
212            | Self::TokenSingleQuoteLiteral(ref source)
213            | Self::TokenArrayLiteral(ref source)
214            | Self::TokenLink(ref source)
215            | Self::TokenParameterPath(ref source)
216            | Self::TokenEndRawBlock(ref source)
217            | Self::BlockNotOpen(ref source) => write!(f, "{}", source)?,
218        }
219        Ok(())
220    }
221}