Skip to main content

oxc_yaml_parser/
error.rs

1//! Error management.
2
3use 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    /// An error pointing at a single byte offset.
18    #[expect(clippy::cast_possible_truncation)] // sources are bounded to u32
19    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    /// The source exceeds the maximum supported size (4 GiB).
27    SourceTooLong,
28    UnexpectedEof,
29    /// A control character or other char that cannot appear in a YAML stream.
30    InvalidChar,
31    /// Tabs used for indentation.
32    TabAsIndent,
33    /// Directives must be followed by a `---` document start marker.
34    ExpectedDocumentStart,
35    /// Content found after a document where a new document or EOF was expected.
36    ExpectedDocumentEnd,
37    /// `&` or `*` with an empty name.
38    EmptyAnchorName,
39    /// Malformed `!` tag property.
40    InvalidTag,
41    /// Malformed block scalar header (`|`/`>` + indicators).
42    InvalidBlockScalarHeader,
43    /// A block scalar's content line is indented less than its detected indentation.
44    InvalidBlockScalarIndent,
45    UnterminatedFlowScalar,
46    /// `,` `[` `]` `{` `}` misplaced in a flow collection.
47    UnexpectedFlowIndicator,
48    /// A simple key is too long or spans multiple lines.
49    InvalidSimpleKey,
50    /// `:` or `-` or `?` in a position where a block collection cannot start.
51    UnexpectedIndicator,
52    /// Mapping value (`:`) in an invalid context.
53    UnexpectedValue,
54    /// A node was expected but something else was found.
55    ExpectedNode,
56    /// Two anchors or two tags on the same node, etc.
57    DuplicatedNodeProperty,
58    /// Generic "unexpected token" during parsing.
59    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 {}