robinson/
error.rs

1use std::error::Error as StdError;
2use std::fmt;
3use std::result::Result as StdResult;
4
5pub(crate) type Result<T = ()> = StdResult<T, Box<Error>>;
6
7#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
8pub enum ErrorKind {
9    MissingRootElement,
10    UnclosedRootElement,
11    UnexpectedCloseElement,
12    TooManyNodes,
13    TooManyAttributes,
14    TooManyNamespaces,
15    TooManyEntityReferences,
16    TooManyStrings,
17    ExpectedLiteral(&'static str),
18    ExpectedSpace,
19    ExpectedQuote,
20    ExpectedEnd,
21    InvalidSyntax,
22    InvalidName,
23    InvalidReference(String),
24    UnknownNamespace(String),
25    UnknownEntity(String),
26}
27
28impl<T> From<ErrorKind> for Result<T> {
29    #[cold]
30    #[inline(never)]
31    fn from(kind: ErrorKind) -> Self {
32        Err(Box::new(Error { kind, pos: None }))
33    }
34}
35
36#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
37pub struct Error {
38    pub kind: ErrorKind,
39    pub pos: Option<(usize, usize)>,
40}
41
42impl StdError for Error {}
43
44impl fmt::Display for Error {
45    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
46        match &self.kind {
47            ErrorKind::MissingRootElement => fmt.write_str("missing root element")?,
48            ErrorKind::UnclosedRootElement => fmt.write_str("unclosed root element")?,
49            ErrorKind::UnexpectedCloseElement => fmt.write_str("unexpected close element")?,
50            ErrorKind::TooManyNodes => fmt.write_str("too many nodes")?,
51            ErrorKind::TooManyAttributes => fmt.write_str("too many attributes")?,
52            ErrorKind::TooManyNamespaces => fmt.write_str("too many namespaces")?,
53            ErrorKind::TooManyEntityReferences => fmt.write_str("too many entity references")?,
54            ErrorKind::TooManyStrings => fmt.write_str("too many strings")?,
55            ErrorKind::ExpectedLiteral(literal) => write!(fmt, "expected literal `{literal}`")?,
56            ErrorKind::ExpectedSpace => fmt.write_str("expected whitespace")?,
57            ErrorKind::ExpectedQuote => fmt.write_str("expected single or double quote")?,
58            ErrorKind::ExpectedEnd => fmt.write_str("expected end")?,
59            ErrorKind::InvalidSyntax => fmt.write_str("invalid syntax")?,
60            ErrorKind::InvalidName => fmt.write_str("invalid name")?,
61            ErrorKind::InvalidReference(value) => write!(fmt, "invalid reference `{value}`")?,
62            ErrorKind::UnknownNamespace(prefix) => write!(fmt, "unknown namespace `{prefix}`")?,
63            ErrorKind::UnknownEntity(name) => write!(fmt, "unknown entity `{name}`")?,
64        }
65
66        if let Some((line, pos)) = self.pos {
67            write!(fmt, " at {line}:{pos}")?;
68        }
69
70        Ok(())
71    }
72}