use std::{marker::PhantomData, ops::RangeTo, str::FromStr};
use nom::{
error::{ContextError, ErrorKind as NomErrorKind, FromExternalError, ParseError},
Err as NomErr, InputLength, Offset, Parser, Slice,
};
pub trait ParserExt<I, O, E>: Parser<I, O, E> + Sized {
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn by_ref(&mut self) -> RefParser<Self> {
RefParser { parser: self }
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn all_consuming(self) -> AllConsuming<Self>
where
I: InputLength,
E: ParseError<I>,
{
AllConsuming { parser: self }
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn complete(self) -> Complete<Self>
where
I: Clone,
E: ParseError<I>,
{
Complete { parser: self }
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn cut(self) -> Cut<Self> {
Cut { parser: self }
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn map_res<F, O2, E2>(self, func: F) -> MapRes<Self, F, O, E2>
where
F: FnMut(O) -> Result<O2, E2>,
E: FromExternalError<I, E2>,
I: Clone,
{
MapRes {
parser: self,
func,
phantom: PhantomData,
}
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn opt(self) -> Optional<Self>
where
I: Clone,
{
Optional { parser: self }
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn recognize(self) -> Recognize<Self, O>
where
I: Clone + Slice<RangeTo<usize>> + Offset,
{
Recognize {
parser: self,
phantom: PhantomData,
}
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn value<T: Clone>(self, value: T) -> Value<T, Self, O> {
Value {
parser: self,
value,
phantom: PhantomData,
}
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn verify<F>(self, verifier: F) -> Verify<Self, F>
where
F: Fn(&O) -> bool,
I: Clone,
E: ParseError<I>,
{
Verify {
parser: self,
verifier,
}
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn context(self, context: &'static str) -> Context<Self>
where
E: ContextError<I>,
I: Clone,
{
Context {
context,
parser: self,
}
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn terminated<F, O2>(self, terminator: F) -> Terminated<Self, F, O2>
where
F: Parser<I, O2, E>,
{
Terminated {
parser: self,
terminator,
phantom: PhantomData,
}
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn precedes<F, O2>(self, successor: F) -> Preceded<F, Self, O>
where
F: Parser<I, O2, E>,
{
successor.preceded_by(self)
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn preceded_by<F, O2>(self, prefix: F) -> Preceded<Self, F, O2>
where
F: Parser<I, O2, E>,
{
Preceded {
parser: self,
prefix,
phantom: PhantomData,
}
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn delimited_by<D, O2>(self, delimiter: D) -> Delimited<Self, D, O2>
where
D: Parser<I, O2, E>,
{
Delimited {
parser: self,
delimiter,
phantom: PhantomData,
}
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn peek(self) -> Peek<Self>
where
I: Clone,
{
Peek { parser: self }
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn not(self) -> Not<Self, O>
where
I: Clone,
E: ParseError<I>,
{
Not {
parser: self,
phantom: PhantomData,
}
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn parse_from_str<'a, T>(self) -> FromStrParser<Self, T>
where
Self: Parser<&'a str, &'a str, E>,
T: FromStr,
E: FromExternalError<&'a str, T::Err>,
{
FromStrParser {
parser: self,
phantom: PhantomData,
}
}
}
impl<I, O, E, P> ParserExt<I, O, E> for P where P: Parser<I, O, E> {}
#[derive(Debug)]
pub struct RefParser<'a, P> {
parser: &'a mut P,
}
impl<'a, I, O, E, P> Parser<I, O, E> for RefParser<'a, P>
where
P: Parser<I, O, E>,
{
#[inline]
fn parse(&mut self, input: I) -> nom::IResult<I, O, E> {
self.parser.parse(input)
}
}
#[derive(Debug, Clone, Copy)]
pub struct AllConsuming<P> {
parser: P,
}
impl<I, O, E, P> Parser<I, O, E> for AllConsuming<P>
where
P: Parser<I, O, E>,
E: ParseError<I>,
I: InputLength,
{
#[inline]
fn parse(&mut self, input: I) -> nom::IResult<I, O, E> {
let (tail, value) = self.parser.parse(input)?;
if tail.input_len() > 0 {
Err(NomErr::Error(E::from_error_kind(tail, NomErrorKind::Eof)))
} else {
Ok((tail, value))
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct Complete<P> {
parser: P,
}
impl<I, O, E, P> Parser<I, O, E> for Complete<P>
where
P: Parser<I, O, E>,
E: ParseError<I>,
I: Clone,
{
#[inline]
fn parse(&mut self, input: I) -> nom::IResult<I, O, E> {
self.parser
.parse(input.clone())
.map_err(move |err| match err {
NomErr::Incomplete(..) => {
NomErr::Error(E::from_error_kind(input, NomErrorKind::Complete))
}
err => err,
})
}
}
#[derive(Debug, Clone, Copy)]
pub struct Cut<P> {
parser: P,
}
impl<I, O, E, P> Parser<I, O, E> for Cut<P>
where
P: Parser<I, O, E>,
{
#[inline]
fn parse(&mut self, input: I) -> nom::IResult<I, O, E> {
self.parser.parse(input).map_err(|err| match err {
NomErr::Error(err) => NomErr::Failure(err),
err => err,
})
}
}
#[derive(Debug, Clone, Copy)]
pub struct Optional<P> {
parser: P,
}
impl<I, O, E, P> Parser<I, Option<O>, E> for Optional<P>
where
P: Parser<I, O, E>,
I: Clone,
{
#[inline]
fn parse(&mut self, input: I) -> nom::IResult<I, Option<O>, E> {
match self.parser.parse(input.clone()) {
Ok((tail, value)) => Ok((tail, Some(value))),
Err(NomErr::Error(_)) => Ok((input, None)),
Err(e) => Err(e),
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct Recognize<P, O> {
parser: P,
phantom: PhantomData<O>,
}
impl<I, O, E, P> Parser<I, I, E> for Recognize<P, O>
where
P: Parser<I, O, E>,
I: Clone + Slice<RangeTo<usize>> + Offset,
{
#[inline]
fn parse(&mut self, input: I) -> nom::IResult<I, I, E> {
let (tail, _) = self.parser.parse(input.clone())?;
let index = input.offset(&tail);
Ok((tail, input.slice(..index)))
}
}
#[derive(Debug, Clone, Copy)]
pub struct Value<T, P, O> {
parser: P,
value: T,
phantom: PhantomData<O>,
}
impl<I, O, E, T, P> Parser<I, T, E> for Value<T, P, O>
where
P: Parser<I, O, E>,
T: Clone,
{
#[inline]
fn parse(&mut self, input: I) -> nom::IResult<I, T, E> {
let (input, _) = self.parser.parse(input)?;
Ok((input, self.value.clone()))
}
}
#[derive(Debug, Clone, Copy)]
pub struct Verify<P, F> {
parser: P,
verifier: F,
}
impl<I, O, E, P, F> Parser<I, O, E> for Verify<P, F>
where
P: Parser<I, O, E>,
E: ParseError<I>,
F: Fn(&O) -> bool,
I: Clone,
{
#[inline]
fn parse(&mut self, input: I) -> nom::IResult<I, O, E> {
let (tail, value) = self.parser.parse(input.clone())?;
match (self.verifier)(&value) {
true => Ok((tail, value)),
false => Err(NomErr::Error(E::from_error_kind(
input,
NomErrorKind::Verify,
))),
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct Context<P> {
context: &'static str,
parser: P,
}
impl<I, O, E, P> Parser<I, O, E> for Context<P>
where
P: Parser<I, O, E>,
E: ContextError<I>,
I: Clone,
{
#[inline]
fn parse(&mut self, input: I) -> nom::IResult<I, O, E> {
self.parser
.parse(input.clone())
.map_err(move |err| err.map(move |err| E::add_context(input, self.context, err)))
}
}
#[derive(Debug, Clone, Copy)]
pub struct Terminated<P1, P2, O2> {
parser: P1,
terminator: P2,
phantom: PhantomData<O2>,
}
impl<I, O1, O2, E, P1, P2> Parser<I, O1, E> for Terminated<P1, P2, O2>
where
P1: Parser<I, O1, E>,
P2: Parser<I, O2, E>,
{
#[inline]
fn parse(&mut self, input: I) -> nom::IResult<I, O1, E> {
let (input, value) = self.parser.parse(input)?;
let (input, _) = self.terminator.parse(input)?;
Ok((input, value))
}
}
#[derive(Debug, Clone, Copy)]
pub struct Preceded<P1, P2, O2> {
parser: P1,
prefix: P2,
phantom: PhantomData<O2>,
}
impl<I, O1, O2, E, P1, P2> Parser<I, O1, E> for Preceded<P1, P2, O2>
where
P1: Parser<I, O1, E>,
P2: Parser<I, O2, E>,
{
#[inline]
fn parse(&mut self, input: I) -> nom::IResult<I, O1, E> {
let (input, _) = self.prefix.parse(input)?;
self.parser.parse(input)
}
}
#[derive(Debug, Clone, Copy)]
pub struct Delimited<P, D, O2> {
parser: P,
delimiter: D,
phantom: PhantomData<O2>,
}
impl<P, D, I, O, E, O2> Parser<I, O, E> for Delimited<P, D, O2>
where
P: Parser<I, O, E>,
D: Parser<I, O2, E>,
{
#[inline]
fn parse(&mut self, input: I) -> nom::IResult<I, O, E> {
let (input, _) = self.delimiter.parse(input)?;
let (input, value) = self.parser.parse(input)?;
let (input, _) = self.delimiter.parse(input)?;
Ok((input, value))
}
}
#[derive(Debug, Clone, Copy)]
pub struct MapRes<P, F, O, E2> {
parser: P,
func: F,
phantom: PhantomData<(O, E2)>,
}
impl<P, F, I, O, E, O2, E2> Parser<I, O2, E> for MapRes<P, F, O, E2>
where
P: Parser<I, O, E>,
F: FnMut(O) -> Result<O2, E2>,
E: FromExternalError<I, E2>,
I: Clone,
{
#[inline]
fn parse(&mut self, input: I) -> nom::IResult<I, O2, E> {
let (tail, value) = self.parser.parse(input.clone())?;
(self.func)(value)
.map(move |value| (tail, value))
.map_err(move |err| {
NomErr::Error(E::from_external_error(input, NomErrorKind::MapRes, err))
})
}
}
#[derive(Debug, Clone, Copy)]
pub struct Peek<P> {
parser: P,
}
impl<I, O, E, P> Parser<I, O, E> for Peek<P>
where
P: Parser<I, O, E>,
I: Clone,
{
#[inline]
fn parse(&mut self, input: I) -> nom::IResult<I, O, E> {
self.parser
.parse(input.clone())
.map(|(_, value)| (input, value))
}
}
#[derive(Debug, Clone, Copy)]
pub struct Not<P, O> {
parser: P,
phantom: PhantomData<O>,
}
impl<I, O, E, P> Parser<I, (), E> for Not<P, O>
where
P: Parser<I, O, E>,
I: Clone,
E: ParseError<I>,
{
#[inline]
fn parse(&mut self, input: I) -> nom::IResult<I, (), E> {
match self.parser.parse(input.clone()) {
Ok(..) => Err(NomErr::Error(E::from_error_kind(input, NomErrorKind::Not))),
Err(NomErr::Error(..)) => Ok((input, ())),
Err(err) => Err(err),
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct FromStrParser<P, T> {
parser: P,
phantom: PhantomData<T>,
}
impl<'a, T, E, P> Parser<&'a str, T, E> for FromStrParser<P, T>
where
P: Parser<&'a str, &'a str, E>,
T: FromStr,
E: FromExternalError<&'a str, T::Err>,
{
#[inline]
fn parse(&mut self, input: &'a str) -> nom::IResult<&'a str, T, E> {
let (tail, value_str) = self.parser.parse(input)?;
match value_str.parse() {
Ok(value) => Ok((tail, value)),
Err(parse_err) => Err(NomErr::Error(E::from_external_error(
input,
NomErrorKind::MapRes,
parse_err,
))),
}
}
}