1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
//! Common error and result handling facilities use displaydoc::Display; use nom::{error::ErrorKind, Offset}; use std::{io, num::TryFromIntError}; use thiserror::Error; /// Error when parsing a file #[derive(Error, Debug, Display)] pub enum FileError { /// IO Error {0:?} IO(#[from] io::Error), /// Count Error {0:?} Count(TryFromIntError), /// Nom Incomplete Incomplete, /// Nom Error at {addr}+{offset}: {code:?} Parse { /// Address of the error addr: u64, /// How far the parser got beyond addr offset: usize, /// The nom error kind code: ErrorKind, }, /// Encoding {0:?} StringEncoding(String), #[cfg(debug_assertions)] /// Not Implemented NotImplemented, /// {0} Custom(&'static str), } /// Trait to hand over a parse error past a buffer pub trait ParseAt<T>: Sized { /// Call this after a <IResult as Finish>::finish fn at(self, addr: u64, slice: &[u8]) -> Result<T, FileError>; } impl<T> ParseAt<T> for Result<T, nom::error::Error<&[u8]>> { fn at(self, addr: u64, slice: &[u8]) -> Result<T, FileError> { self.map_err(|e| FileError::Parse { addr, code: e.code, offset: slice.offset(e.input), }) } } /*/// Nom error #[derive(Debug, Error)] pub enum ParseError { /// Parsing was not successful #[error("Error at -{0}, {1:?}")] Error(usize, ErrorKind), /// A parse was recognized but invalid #[error("Failure at -{0}, {1:?}")] Failure(usize, ErrorKind), /// Needs more data #[error("Incomplete")] Incomplete, } impl<I: InputLength> From<nom::Err<nom::error::Error<I>>> for ParseError { fn from(error: nom::Err<nom::error::Error<I>>) -> Self { match error { nom::Err::Error(e) => Self::Error(e.input.input_len(), e.code), nom::Err::Failure(e) => Self::Failure(e.input.input_len(), e.code), nom::Err::Incomplete(_) => Self::Incomplete, } } }*/ /// Result when parsing a file pub type FileResult<T> = Result<T, FileError>;