use core::{marker::PhantomData, ops::RangeTo, str::FromStr};
use nom::{
error::{ErrorKind as NomErrorKind, FromExternalError, ParseError},
Err as NomErr, InputLength, Offset, Parser, Slice,
};
use crate::context::ContextError;
#[inline(always)]
fn must_be_a_parser<I, O, E, P: Parser<I, O, E>>(parser: P) -> P {
parser
}
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> {
must_be_a_parser(RefParser { parser: self })
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn all_consuming(self) -> AllConsuming<Self>
where
I: InputLength,
E: ParseError<I>,
{
must_be_a_parser(AllConsuming { parser: self })
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn complete(self) -> Complete<Self>
where
I: Clone,
E: ParseError<I>,
{
must_be_a_parser(Complete { parser: self })
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn cut(self) -> Cut<Self> {
must_be_a_parser(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,
{
must_be_a_parser(MapRes {
parser: self,
func,
phantom: PhantomData,
})
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn map_res_cut<F, O2, E2>(self, func: F) -> MapResCut<Self, F, O, E2>
where
F: FnMut(O) -> Result<O2, E2>,
E: FromExternalError<I, E2>,
I: Clone,
{
must_be_a_parser(MapResCut {
parser: self,
func,
phantom: PhantomData,
})
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn opt(self) -> Optional<Self>
where
I: Clone,
{
must_be_a_parser(Optional { parser: self })
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn recognize(self) -> Recognize<Self, O>
where
I: Clone + Slice<RangeTo<usize>> + Offset,
{
must_be_a_parser(Recognize {
parser: self.with_recognized(),
phantom: PhantomData,
})
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn with_recognized(self) -> WithRecognized<Self>
where
I: Clone + Slice<RangeTo<usize>> + Offset,
{
must_be_a_parser(WithRecognized { parser: self })
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn value<T: Clone>(self, value: T) -> Value<T, Self, O> {
must_be_a_parser(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>,
{
must_be_a_parser(Verify {
parser: self,
verifier,
})
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn context<C>(self, context: C) -> Context<Self, C>
where
E: ContextError<I, C>,
I: Clone,
C: Clone,
{
must_be_a_parser(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>,
{
must_be_a_parser(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>,
{
must_be_a_parser(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>,
{
must_be_a_parser(Preceded {
parser: self,
prefix,
phantom: PhantomData,
})
}
fn opt_precedes<F, O2>(self, successor: F) -> OptionalPreceded<Self, F>
where
E: ParseError<I>,
I: Clone,
F: Parser<I, O2, E>,
{
must_be_a_parser(OptionalPreceded {
prefix: self,
parser: successor,
})
}
fn opt_preceded_by<F, O2>(self, prefix: F) -> OptionalPreceded<F, Self>
where
E: ParseError<I>,
I: Clone,
F: Parser<I, O2, E>,
{
must_be_a_parser(OptionalPreceded {
parser: self,
prefix,
})
}
#[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>,
{
must_be_a_parser(Delimited {
parser: self,
delimiter,
phantom: PhantomData,
})
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn peek(self) -> Peek<Self>
where
I: Clone,
{
must_be_a_parser(Peek { parser: self })
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn not(self) -> Not<Self, O>
where
I: Clone,
E: ParseError<I>,
{
must_be_a_parser(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<I, &'a str, E>,
I: Clone,
T: FromStr,
E: FromExternalError<I, T::Err>,
{
must_be_a_parser(FromStrParser {
parser: self,
phantom: PhantomData,
})
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn parse_from_str_cut<'a, T>(self) -> FromStrCutParser<Self, T>
where
Self: Parser<I, &'a str, E>,
I: Clone,
T: FromStr,
E: FromExternalError<I, T::Err>,
{
must_be_a_parser(FromStrCutParser {
parser: self,
phantom: PhantomData,
})
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn array(self) -> ArrayParser<Self> {
ArrayParser { parser: self }
}
#[inline]
#[must_use = "Parsers do nothing unless used"]
fn separated_array<F, O2>(self, separator: F) -> SeparatedArrayParser<Self, F, O2>
where
F: Parser<I, O2, E>,
{
SeparatedArrayParser {
parser: self,
separator,
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: WithRecognized<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> {
self.parser
.parse(input)
.map(|(tail, (recognized, _))| (tail, recognized))
}
}
#[derive(Debug, Clone, Copy)]
pub struct WithRecognized<P> {
parser: P,
}
impl<I, O, E, P> Parser<I, (I, O), E> for WithRecognized<P>
where
P: Parser<I, O, E>,
I: Clone + Slice<RangeTo<usize>> + Offset,
{
#[inline]
fn parse(&mut self, input: I) -> nom::IResult<I, (I, O), E> {
let (tail, output) = self.parser.parse(input.clone())?;
let index = input.offset(&tail);
Ok((tail, (input.slice(..index), output)))
}
}
#[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> {
self.parser
.parse(input)
.map(|(input, _)| (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, C> {
context: C,
parser: P,
}
impl<I, O, E, P, C> Parser<I, O, E> for Context<P, C>
where
P: Parser<I, O, E>,
E: ContextError<I, C>,
I: Clone,
C: 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.clone(), err))
})
}
}
#[derive(Debug, Clone, Copy)]
pub struct ReplaceError<P, E> {
new_error: E,
parser: P,
}
impl<I, O, F, E, P> Parser<I, O, E> for ReplaceError<P, F>
where
P: Parser<I, O, ()>,
F: FnMut() -> E,
{
fn parse(&mut self, input: I) -> nom::IResult<I, O, E> {
self.parser
.parse(input)
.map_err(|err| err.map(|()| (self.new_error)()))
}
}
#[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 OptionalPreceded<P1, P2> {
parser: P2,
prefix: P1,
}
impl<I, O1, O2, E, P1, P2> Parser<I, (Option<O1>, O2), E> for OptionalPreceded<P1, P2>
where
P1: Parser<I, O1, E>,
P2: Parser<I, O2, E>,
I: Clone,
E: ParseError<I>,
{
#[inline]
fn parse(&mut self, input: I) -> nom::IResult<I, (Option<O1>, O2), E> {
match self.prefix.parse(input.clone()) {
Ok((input, o1)) => self
.parser
.parse(input)
.map(|(tail, o2)| (tail, (Some(o1), o2))),
Err(NomErr::Error(err1)) => self
.parser
.parse(input)
.map(|(tail, o2)| (tail, (None, o2)))
.map_err(|err2| err2.map(|err2| err1.or(err2))),
Err(err) => Err(err),
}
}
}
#[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 MapResCut<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 MapResCut<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::Failure(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, I, E, P> Parser<I, T, E> for FromStrParser<P, T>
where
P: Parser<I, &'a str, E>,
I: Clone,
T: FromStr,
E: FromExternalError<I, T::Err>,
{
#[inline]
fn parse(&mut self, input: I) -> nom::IResult<I, T, E> {
let (tail, value_str) = self.parser.parse(input.clone())?;
match value_str.parse() {
Ok(value) => Ok((tail, value)),
Err(parse_err) => Err(NomErr::Error(E::from_external_error(
input,
NomErrorKind::MapRes,
parse_err,
))),
}
}
}
#[cfg(feature = "error")]
#[test]
fn from_str_parser_non_str_input() {
use core::str::from_utf8;
use cool_asserts::assert_matches;
use nom::{
character::complete::{char, digit1},
Err as NomErr,
};
use crate::error::{BaseErrorKind, ErrorTree, Expectation};
let mut parser = digit1
.opt_preceded_by(char('-'))
.recognize()
.map_res(from_utf8)
.parse_from_str();
assert_matches!(parser.parse(b"-123"), Ok((b"", -123)));
let branches = assert_matches!(parser.parse(b"abc"), Err(NomErr::Error(ErrorTree::Alt(branches))) => branches);
assert_matches!(
branches.as_slice(),
[
ErrorTree::Base {
location: b"abc",
kind: BaseErrorKind::Expected(Expectation::Char('-'))
},
ErrorTree::Base {
location: b"abc",
kind: BaseErrorKind::Expected(Expectation::Digit)
}
]
)
}
#[derive(Debug, Clone, Copy)]
pub struct FromStrCutParser<P, T> {
parser: P,
phantom: PhantomData<T>,
}
impl<'a, I, T, E, P> Parser<I, T, E> for FromStrCutParser<P, T>
where
P: Parser<I, &'a str, E>,
I: Clone,
T: FromStr,
E: FromExternalError<I, T::Err>,
{
#[inline]
fn parse(&mut self, input: I) -> nom::IResult<I, T, E> {
let (tail, value_str) = self.parser.parse(input.clone())?;
match value_str.parse() {
Ok(value) => Ok((tail, value)),
Err(parse_err) => Err(NomErr::Failure(E::from_external_error(
input,
NomErrorKind::MapRes,
parse_err,
))),
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct ArrayParser<P> {
parser: P,
}
impl<P, I, O, E, const N: usize> Parser<I, [O; N], E> for ArrayParser<P>
where
P: Parser<I, O, E>,
{
fn parse(&mut self, mut input: I) -> nom::IResult<I, [O; N], E> {
let array = brownstone::build![{
let (tail, value) = self.parser.parse(input)?;
input = tail;
value
}];
Ok((input, array))
}
}
#[derive(Debug, Clone, Copy)]
pub struct SeparatedArrayParser<P1, P2, O2> {
parser: P1,
separator: P2,
phantom: PhantomData<O2>,
}
impl<I, O1, O2, E, P1, P2, const N: usize> Parser<I, [O1; N], E>
for SeparatedArrayParser<P1, P2, O2>
where
P1: Parser<I, O1, E>,
P2: Parser<I, O2, E>,
{
fn parse(&mut self, mut input: I) -> nom::IResult<I, [O1; N], E> {
let array = brownstone::build!(|index: usize| {
let tail = match index {
0 => input,
_ => self.separator.parse(input)?.0,
};
let (tail, value) = self.parser.parse(tail)?;
input = tail;
value
});
Ok((input, array))
}
}