#![warn(rust_2018_idioms)]
#![warn(missing_docs)]
#![allow(deprecated)]
pub mod nom {
pub use nom::{error::ErrorKind, error::Error, Err, IResult, Needed};
}
pub mod expr;
pub mod literal;
pub mod token;
#[derive(Debug)]
pub enum ErrorKind {
ExactToken(token::Kind, &'static [u8]),
ExactTokens(token::Kind, &'static [&'static str]),
TypedToken(token::Kind),
UnknownIdentifier,
InvalidLiteral,
Partial,
Parser(nom::ErrorKind),
}
impl From<nom::ErrorKind> for ErrorKind {
fn from(k: nom::ErrorKind) -> Self {
ErrorKind::Parser(k)
}
}
impl From<u32> for ErrorKind {
fn from(_: u32) -> Self {
ErrorKind::InvalidLiteral
}
}
#[derive(Debug)]
pub struct Error<I> {
pub input: I,
pub error: ErrorKind,
}
impl<I> From<(I, nom::ErrorKind)> for Error<I> {
fn from(e: (I, nom::ErrorKind)) -> Self {
Self::from((e.0, ErrorKind::from(e.1)))
}
}
impl<I> From<(I, ErrorKind)> for Error<I> {
fn from(e: (I, ErrorKind)) -> Self {
Self {
input: e.0,
error: e.1,
}
}
}
impl<I> From<::nom::error::Error<I>> for Error<I> {
fn from(e: ::nom::error::Error<I>) -> Self {
Self {
input: e.input,
error: e.code.into(),
}
}
}
impl<I> ::nom::error::ParseError<I> for Error<I> {
fn from_error_kind(input: I, kind: nom::ErrorKind) -> Self {
Self {
input,
error: kind.into(),
}
}
fn append(_: I, _: nom::ErrorKind, other: Self) -> Self {
other
}
}
trait ToCexprResult<I, O> {
fn to_cexpr_result(self) -> nom::IResult<I, O, Error<I>>;
}
impl<I, O, E> ToCexprResult<I, O> for nom::IResult<I, O, E>
where
Error<I>: From<E>,
{
fn to_cexpr_result(self) -> nom::IResult<I, O, Error<I>> {
match self {
Ok(v) => Ok(v),
Err(nom::Err::Incomplete(n)) => Err(nom::Err::Incomplete(n)),
Err(nom::Err::Error(e)) => Err(nom::Err::Error(e.into())),
Err(nom::Err::Failure(e)) => Err(nom::Err::Failure(e.into())),
}
}
}
pub fn assert_full_parse<'i, I: 'i, O, E>(
result: nom::IResult<&'i [I], O, E>,
) -> nom::IResult<&'i [I], O, Error<&'i [I]>>
where
Error<&'i [I]>: From<E>,
{
match result.to_cexpr_result() {
Ok((rem, output)) => {
if rem.is_empty() {
Ok((rem, output))
} else {
Err(nom::Err::Error((rem, ErrorKind::Partial).into()))
}
}
Err(nom::Err::Incomplete(n)) => Err(nom::Err::Incomplete(n)),
Err(nom::Err::Failure(e)) => Err(nom::Err::Failure(e)),
Err(nom::Err::Error(e)) => Err(nom::Err::Error(e)),
}
}