1use crate::pos::Span;
4use std::fmt::Display;
5
6#[derive(Clone, Debug)]
7pub struct Error {
8 pub kind: ErrorKind,
9 pub span: Span,
10}
11
12impl Error {
13 pub(crate) fn new(kind: ErrorKind, span: Span) -> Self {
14 Self { kind, span }
15 }
16
17 #[expect(clippy::cast_possible_truncation)] pub(crate) fn point(kind: ErrorKind, at: usize) -> Self {
20 Self { kind, span: Span::new(at as u32, at as u32 + 1) }
21 }
22}
23
24#[derive(Clone, Debug, PartialEq, Eq)]
25pub enum ErrorKind {
26 SourceTooLong,
28 UnexpectedEof,
29 InvalidChar,
31 TabAsIndent,
33 ExpectedDocumentStart,
35 ExpectedDocumentEnd,
37 EmptyAnchorName,
39 InvalidTag,
41 InvalidBlockScalarHeader,
43 InvalidBlockScalarIndent,
45 UnterminatedFlowScalar,
46 UnexpectedFlowIndicator,
48 InvalidSimpleKey,
50 UnexpectedIndicator,
52 UnexpectedValue,
54 ExpectedNode,
56 DuplicatedNodeProperty,
58 UnexpectedToken(&'static str),
60}
61
62impl Display for Error {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 write!(f, "{} at {}..{}", self.kind, self.span.start, self.span.end)
65 }
66}
67
68impl Display for ErrorKind {
69 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70 let message = match self {
71 ErrorKind::SourceTooLong => "source exceeds the maximum supported size (4 GiB)",
72 ErrorKind::UnexpectedEof => "unexpected end of input",
73 ErrorKind::InvalidChar => "invalid character",
74 ErrorKind::TabAsIndent => "tabs are not allowed as indentation",
75 ErrorKind::ExpectedDocumentStart => "expected document start marker `---`",
76 ErrorKind::ExpectedDocumentEnd => "expected the document to end",
77 ErrorKind::EmptyAnchorName => "anchor or alias name cannot be empty",
78 ErrorKind::InvalidTag => "invalid tag property",
79 ErrorKind::InvalidBlockScalarHeader => "invalid block scalar header",
80 ErrorKind::InvalidBlockScalarIndent => "invalid block scalar indentation",
81 ErrorKind::UnterminatedFlowScalar => "unterminated quoted scalar",
82 ErrorKind::UnexpectedFlowIndicator => "unexpected flow collection indicator",
83 ErrorKind::InvalidSimpleKey => "invalid simple key",
84 ErrorKind::UnexpectedIndicator => "unexpected indicator",
85 ErrorKind::UnexpectedValue => "mapping values are not allowed in this context",
86 ErrorKind::ExpectedNode => "expected a node",
87 ErrorKind::DuplicatedNodeProperty => "duplicated node property",
88 ErrorKind::UnexpectedToken(what) => {
89 return write!(f, "unexpected {what}");
90 }
91 };
92 f.write_str(message)
93 }
94}
95
96impl std::error::Error for Error {}