obeli_sk_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 #[inline]
47 pub(crate) fn unexpected<F, M, P>(found: F, message: M, pos: P) -> Self
48 where
49 F: fmt::Display,
50 M: Into<Box<str>>,
51 P: Into<Position>,
52 {
53 Self::Syntax(
54 format!("unexpected {found}, {}", message.into().as_ref()).into(),
55 pos.into(),
56 )
57 }
58}
59
60impl fmt::Display for Error {
61 #[inline]
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 match self {
64 Self::IO(e) => e.fmt(f),
65 Self::Syntax(e, pos) => write!(
66 f,
67 "{e} at line {}, col {}",
68 pos.line_number(),
69 pos.column_number()
70 ),
71 }
72 }
73}
74
75impl error::Error for Error {
76 #[inline]
77 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
78 match self {
79 Self::IO(err) => Some(err),
80 Self::Syntax(_, _) => None,
81 }
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88 use std::{error::Error as _, io};
89
90 #[test]
91 fn syntax() {
92 let err = Error::syntax("testing", Position::new(1, 1));
93 if let Error::Syntax(err, pos) = err {
94 assert_eq!(err.as_ref(), "testing");
95 assert_eq!(pos, Position::new(1, 1));
96 } else {
97 unreachable!()
98 }
99
100 let err = Error::syntax("testing", Position::new(1, 1));
101 assert_eq!(err.to_string(), "testing at line 1, col 1");
102 assert!(err.source().is_none());
103 }
104
105 #[test]
106 fn io() {
107 let custom_error = io::Error::other("I/O error");
108 let err = custom_error.into();
109 if let Error::IO(err) = err {
110 assert_eq!(err.to_string(), "I/O error");
111 } else {
112 unreachable!()
113 }
114
115 let custom_error = io::Error::other("I/O error");
116 let err: Error = custom_error.into();
117 assert_eq!(err.to_string(), "I/O error");
118 err.source().map_or_else(
119 || unreachable!(),
120 |io_err| {
121 assert_eq!(io_err.to_string(), "I/O error");
122 },
123 );
124 }
125}