diff --git a/Cargo.toml b/Cargo.toml index b6287b5..64ca685 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,4 @@ rust-version = "1.72.0" [dependencies] nom = "7.1" +thiserror = "1.0.50" diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..259f5b0 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,49 @@ +use nom::{ + error::{ErrorKind, FromExternalError, ParseError}, + IResult, +}; + +/// The error type for AsciiDoc parsing operations. +#[non_exhaustive] +#[derive(Clone, Debug, thiserror::Error, PartialEq, Eq)] +pub enum Error { + /// AsciiDoc data was incomplete. + #[error("Incomplete data, missing: {0:?}")] + Incomplete(nom::Needed), + + /// Error from nom parsing framework. + #[error("nom error: {0:?}")] + NomError(ErrorKind), +} + +impl<'a> ParseError<&'a str> for Error { + fn from_error_kind(_input: &'a str, kind: ErrorKind) -> Self { + Error::NomError(kind) + } + + fn append(_input: &'a str, kind: ErrorKind, _other: Self) -> Self { + Error::NomError(kind) + } +} + +impl From> for Error { + fn from(e: nom::Err) -> Self { + match e { + nom::Err::Incomplete(n) => Self::Incomplete(n), + nom::Err::Error(e) | nom::Err::Failure(e) => e, + } + } +} + +impl FromExternalError for Error { + fn from_external_error(_input: I, kind: ErrorKind, _e: E) -> Error { + Error::NomError(kind) + } +} + +/// Holds the result of AsciiDoc parsing functions. +/// +/// Note that this type is also a [`Result`], so the usual functions (`map`, +/// `unwrap`, etc.) are available. +#[allow(dead_code)] // TEMPORARY +pub type ParseResult<'a, T, E = Error> = IResult<&'a str, T, E>; diff --git a/src/lib.rs b/src/lib.rs index 069f003..e701ecb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,9 @@ #![deny(warnings)] #![doc = include_str!("../README.md")] +mod error; +pub use error::{Error, ParseResult}; + pub(crate) mod primitives; pub mod strings;