use std::{fmt}; use super::SourcePosition; use position::get_line_and_column; /// The representation of an s-expression parse error. pub struct Error { /// The error message. pub message: &'static str, /// Position in the source string where the error was detected pub pos: SourcePosition, } /// Since errors are the uncommon case, they're boxed. This keeps the size of /// structs down, which helps performance in the common case. /// /// For example, an `ERes<()>` becomes 8 bytes, instead of the 24 bytes it would /// be if `Err` were unboxed. type Err = Box; /// Helps clean up type signatures, but shouldn't be exposed to the outside /// world. pub(crate) type ERes = Result; impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { write!(f, "{}: {}", self.pos, self.message) } } impl fmt::Debug for Error { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { write!(f, "{}", self) } } impl std::error::Error for Error {} #[cold] fn err_impl(message: &'static str, s: &str, pos: usize) -> Err { Box::new(Error { message, pos: get_line_and_column(s, pos), }) } /// Build an error with span information pub(crate) fn err(message: &'static str, s: &str, pos: usize) -> ERes { Err(err_impl(message, s, pos)) }