boa_parser/lexer/
error.rs1use boa_ast::Position;
9use std::{error, fmt, io};
10
11#[derive(Debug)]
13pub enum Error {
14 IO(io::Error),
17
18 Syntax(Box<str>, Position),
25}
26
27impl From<io::Error> for Error {
28 #[inline]
29 fn from(err: io::Error) -> Self {
30 Self::IO(err)
31 }
32}
33
34impl Error {
35 #[inline]
37 pub(crate) fn syntax<M, P>(err: M, pos: P) -> Self
38 where
39 M: Into<Box<str>>,
40 P: Into<Position>,
41 {
42 Self::Syntax(err.into(), pos.into())
43 }
44}
45
46impl fmt::Display for Error {
47 #[inline]
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 match self {
50 Self::IO(e) => e.fmt(f),
51 Self::Syntax(e, pos) => write!(
52 f,
53 "{e} at line {}, col {}",
54 pos.line_number(),
55 pos.column_number()
56 ),
57 }
58 }
59}
60
61impl error::Error for Error {
62 #[inline]
63 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
64 match self {
65 Self::IO(err) => Some(err),
66 Self::Syntax(_, _) => None,
67 }
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74 use std::{error::Error as _, io};
75
76 #[test]
77 fn syntax() {
78 let err = Error::syntax("testing", Position::new(1, 1));
79 if let Error::Syntax(err, pos) = err {
80 assert_eq!(err.as_ref(), "testing");
81 assert_eq!(pos, Position::new(1, 1));
82 } else {
83 unreachable!()
84 }
85
86 let err = Error::syntax("testing", Position::new(1, 1));
87 assert_eq!(err.to_string(), "testing at line 1, col 1");
88 assert!(err.source().is_none());
89 }
90
91 #[test]
92 fn io() {
93 let custom_error = io::Error::other("I/O error");
94 let err = custom_error.into();
95 if let Error::IO(err) = err {
96 assert_eq!(err.to_string(), "I/O error");
97 } else {
98 unreachable!()
99 }
100
101 let custom_error = io::Error::other("I/O error");
102 let err: Error = custom_error.into();
103 assert_eq!(err.to_string(), "I/O error");
104 err.source().map_or_else(
105 || unreachable!(),
106 |io_err| {
107 assert_eq!(io_err.to_string(), "I/O error");
108 },
109 );
110 }
111}