use crate::error::{ContextError, ErrMode, ErrorKind, FromExternalError, Needed, ParseError};
use crate::lib::std::borrow::Borrow;
use crate::lib::std::convert;
use crate::lib::std::ops::Range;
use crate::stream::{Location, Stream};
use crate::stream::{Offset, StreamIsPartial};
use crate::trace::trace;
use crate::trace::trace_result;
use crate::*;
#[cfg(test)]
mod tests;
#[inline]
pub fn rest<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E>
where
I: Stream,
{
trace("rest", move |input: I| {
Ok(input.next_slice(input.eof_offset()))
})(input)
}
#[inline]
pub fn rest_len<I, E: ParseError<I>>(input: I) -> IResult<I, usize, E>
where
I: Stream,
{
trace("rest_len", move |input: I| {
let len = input.eof_offset();
Ok((input, len))
})(input)
}
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct ByRef<'p, P> {
p: &'p mut P,
}
impl<'p, P> ByRef<'p, P> {
#[inline(always)]
pub(crate) fn new(p: &'p mut P) -> Self {
Self { p }
}
}
impl<'p, I, O, E, P: Parser<I, O, E>> Parser<I, O, E> for ByRef<'p, P> {
fn parse_next(&mut self, i: I) -> IResult<I, O, E> {
self.p.parse_next(i)
}
}
#[deprecated(since = "0.1.0", note = "Replaced with `Parser::map")]
#[cfg_attr(feature = "unstable-doc", doc(hidden))]
pub fn map<I, O1, O2, E, F, G>(mut parser: F, mut f: G) -> impl FnMut(I) -> IResult<I, O2, E>
where
F: Parser<I, O1, E>,
G: FnMut(O1) -> O2,
{
move |input: I| {
let (input, o1) = parser.parse_next(input)?;
Ok((input, f(o1)))
}
}
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct Map<F, G, O1> {
f: F,
g: G,
phantom: core::marker::PhantomData<O1>,
}
impl<F, G, O1> Map<F, G, O1> {
#[inline(always)]
pub(crate) fn new(f: F, g: G) -> Self {
Self {
f,
g,
phantom: Default::default(),
}
}
}
impl<I, O1, O2, E, F: Parser<I, O1, E>, G: Fn(O1) -> O2> Parser<I, O2, E> for Map<F, G, O1> {
fn parse_next(&mut self, i: I) -> IResult<I, O2, E> {
match self.f.parse_next(i) {
Err(e) => Err(e),
Ok((i, o)) => Ok((i, (self.g)(o))),
}
}
}
#[deprecated(since = "0.1.0", note = "Replaced with `Parser::map_res")]
#[cfg_attr(feature = "unstable-doc", doc(hidden))]
pub fn map_res<I: Clone, O1, O2, E: FromExternalError<I, E2>, E2, F, G>(
mut parser: F,
mut f: G,
) -> impl FnMut(I) -> IResult<I, O2, E>
where
F: Parser<I, O1, E>,
G: FnMut(O1) -> Result<O2, E2>,
{
move |input: I| {
let i = input.clone();
let (input, o1) = parser.parse_next(input)?;
match f(o1) {
Ok(o2) => Ok((input, o2)),
Err(e) => Err(ErrMode::from_external_error(i, ErrorKind::MapRes, e)),
}
}
}
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct MapRes<F, G, O1> {
f: F,
g: G,
phantom: core::marker::PhantomData<O1>,
}
impl<F, G, O1> MapRes<F, G, O1> {
#[inline(always)]
pub(crate) fn new(f: F, g: G) -> Self {
Self {
f,
g,
phantom: Default::default(),
}
}
}
impl<I, O1, O2, E, E2, F, G> Parser<I, O2, E> for MapRes<F, G, O1>
where
I: Clone,
F: Parser<I, O1, E>,
G: FnMut(O1) -> Result<O2, E2>,
E: FromExternalError<I, E2>,
{
fn parse_next(&mut self, input: I) -> IResult<I, O2, E> {
let i = input.clone();
let (input, o1) = self.f.parse_next(input)?;
let res = match (self.g)(o1) {
Ok(o2) => Ok((input, o2)),
Err(e) => Err(ErrMode::from_external_error(i, ErrorKind::MapRes, e)),
};
trace_result("verify", &res);
res
}
}
#[deprecated(since = "0.1.0", note = "Replaced with `Parser::verify_map")]
#[cfg_attr(feature = "unstable-doc", doc(hidden))]
pub fn map_opt<I: Clone, O1, O2, E: ParseError<I>, F, G>(
mut parser: F,
mut f: G,
) -> impl FnMut(I) -> IResult<I, O2, E>
where
F: Parser<I, O1, E>,
G: FnMut(O1) -> Option<O2>,
{
move |input: I| {
let i = input.clone();
let (input, o1) = parser.parse_next(input)?;
match f(o1) {
Some(o2) => Ok((input, o2)),
None => Err(ErrMode::from_error_kind(i, ErrorKind::Verify)),
}
}
}
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct VerifyMap<F, G, O1> {
f: F,
g: G,
phantom: core::marker::PhantomData<O1>,
}
impl<F, G, O1> VerifyMap<F, G, O1> {
#[inline(always)]
pub(crate) fn new(f: F, g: G) -> Self {
Self {
f,
g,
phantom: Default::default(),
}
}
}
impl<I, O1, O2, E, F, G> Parser<I, O2, E> for VerifyMap<F, G, O1>
where
I: Clone,
F: Parser<I, O1, E>,
G: FnMut(O1) -> Option<O2>,
E: ParseError<I>,
{
fn parse_next(&mut self, input: I) -> IResult<I, O2, E> {
let i = input.clone();
let (input, o1) = self.f.parse_next(input)?;
let res = match (self.g)(o1) {
Some(o2) => Ok((input, o2)),
None => Err(ErrMode::from_error_kind(i, ErrorKind::Verify)),
};
trace_result("verify", &res);
res
}
}
#[deprecated(since = "0.1.0", note = "Replaced with `Parser::and_then")]
#[cfg_attr(feature = "unstable-doc", doc(hidden))]
pub fn map_parser<I, O1, O2, E: ParseError<I>, F, G>(
mut parser: F,
mut applied_parser: G,
) -> impl FnMut(I) -> IResult<I, O2, E>
where
F: Parser<I, O1, E>,
G: Parser<O1, O2, E>,
{
move |input: I| {
let (input, o1) = parser.parse_next(input)?;
let (_, o2) = applied_parser.parse_next(o1)?;
Ok((input, o2))
}
}
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct AndThen<F, G, O1> {
f: F,
g: G,
phantom: core::marker::PhantomData<O1>,
}
impl<F, G, O1> AndThen<F, G, O1>
where
O1: StreamIsPartial,
{
#[inline(always)]
pub(crate) fn new(f: F, g: G) -> Self {
Self {
f,
g,
phantom: Default::default(),
}
}
}
impl<I, O1, O2, E, F: Parser<I, O1, E>, G: Parser<O1, O2, E>> Parser<I, O2, E> for AndThen<F, G, O1>
where
O1: StreamIsPartial,
{
fn parse_next(&mut self, i: I) -> IResult<I, O2, E> {
let (i, mut o1) = self.f.parse_next(i)?;
let _ = o1.complete();
let (_, o2) = self.g.parse_next(o1)?;
Ok((i, o2))
}
}
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct ParseTo<P, O1, O2> {
p: P,
o1: core::marker::PhantomData<O1>,
o2: core::marker::PhantomData<O2>,
}
impl<P, O1, O2> ParseTo<P, O1, O2> {
#[inline(always)]
pub(crate) fn new(p: P) -> Self {
Self {
p,
o1: Default::default(),
o2: Default::default(),
}
}
}
impl<I, O1, O2, E, P> Parser<I, O2, E> for ParseTo<P, O1, O2>
where
I: Stream,
O1: crate::stream::ParseSlice<O2>,
E: ParseError<I>,
P: Parser<I, O1, E>,
{
fn parse_next(&mut self, i: I) -> IResult<I, O2, E> {
let input = i.clone();
let (i, o) = self.p.parse_next(i)?;
let res = o
.parse_slice()
.ok_or_else(|| ErrMode::from_error_kind(input, ErrorKind::Verify));
trace_result("verify", &res);
Ok((i, res?))
}
}
#[deprecated(since = "0.1.0", note = "Replaced with `Parser::flat_map")]
#[cfg_attr(feature = "unstable-doc", doc(hidden))]
pub fn flat_map<I, O1, O2, E: ParseError<I>, F, G, H>(
mut parser: F,
mut applied_parser: G,
) -> impl FnMut(I) -> IResult<I, O2, E>
where
F: Parser<I, O1, E>,
G: FnMut(O1) -> H,
H: Parser<I, O2, E>,
{
move |input: I| {
let (input, o1) = parser.parse_next(input)?;
applied_parser(o1).parse_next(input)
}
}
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct FlatMap<F, G, O1> {
f: F,
g: G,
phantom: core::marker::PhantomData<O1>,
}
impl<F, G, O1> FlatMap<F, G, O1> {
#[inline(always)]
pub(crate) fn new(f: F, g: G) -> Self {
Self {
f,
g,
phantom: Default::default(),
}
}
}
impl<I, O1, O2, E, F: Parser<I, O1, E>, G: FnMut(O1) -> H, H: Parser<I, O2, E>> Parser<I, O2, E>
for FlatMap<F, G, O1>
{
fn parse_next(&mut self, i: I) -> IResult<I, O2, E> {
let (i, o1) = self.f.parse_next(i)?;
(self.g)(o1).parse_next(i)
}
}
pub fn opt<I: Stream, O, E: ParseError<I>, F>(mut f: F) -> impl FnMut(I) -> IResult<I, Option<O>, E>
where
F: Parser<I, O, E>,
{
trace("opt", move |input: I| {
let i = input.clone();
match f.parse_next(input) {
Ok((i, o)) => Ok((i, Some(o))),
Err(ErrMode::Backtrack(_)) => Ok((i, None)),
Err(e) => Err(e),
}
})
}
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct And<F, G> {
f: F,
g: G,
}
impl<F, G> And<F, G> {
#[inline(always)]
pub(crate) fn new(f: F, g: G) -> Self {
Self { f, g }
}
}
impl<I, O1, O2, E, F: Parser<I, O1, E>, G: Parser<I, O2, E>> Parser<I, (O1, O2), E> for And<F, G> {
fn parse_next(&mut self, i: I) -> IResult<I, (O1, O2), E> {
let (i, o1) = self.f.parse_next(i)?;
let (i, o2) = self.g.parse_next(i)?;
Ok((i, (o1, o2)))
}
}
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct Or<F, G> {
f: F,
g: G,
}
impl<F, G> Or<F, G> {
#[inline(always)]
pub(crate) fn new(f: F, g: G) -> Self {
Self { f, g }
}
}
impl<I: Clone, O, E: crate::error::ParseError<I>, F: Parser<I, O, E>, G: Parser<I, O, E>>
Parser<I, O, E> for Or<F, G>
{
fn parse_next(&mut self, i: I) -> IResult<I, O, E> {
match self.f.parse_next(i.clone()) {
Err(ErrMode::Backtrack(e1)) => match self.g.parse_next(i) {
Err(ErrMode::Backtrack(e2)) => Err(ErrMode::Backtrack(e1.or(e2))),
res => res,
},
res => res,
}
}
}
pub fn cond<I, O, E: ParseError<I>, F>(
b: bool,
mut f: F,
) -> impl FnMut(I) -> IResult<I, Option<O>, E>
where
I: Stream,
F: Parser<I, O, E>,
{
trace("cond", move |input: I| {
if b {
match f.parse_next(input) {
Ok((i, o)) => Ok((i, Some(o))),
Err(e) => Err(e),
}
} else {
Ok((input, None))
}
})
}
#[doc(alias = "look_ahead")]
#[doc(alias = "rewind")]
pub fn peek<I: Stream, O, E: ParseError<I>, F>(mut f: F) -> impl FnMut(I) -> IResult<I, O, E>
where
F: Parser<I, O, E>,
{
trace("peek", move |input: I| {
let i = input.clone();
match f.parse_next(input) {
Ok((_, o)) => Ok((i, o)),
Err(e) => Err(e),
}
})
}
#[doc(alias = "end")]
#[doc(alias = "eoi")]
pub fn eof<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E>
where
I: Stream,
{
trace("eof", move |input: I| {
if input.eof_offset() == 0 {
Ok(input.next_slice(0))
} else {
Err(ErrMode::from_error_kind(input, ErrorKind::Eof))
}
})(input)
}
#[deprecated(since = "0.1.0", note = "Replaced with `Parser::complete_err")]
#[cfg_attr(feature = "unstable-doc", doc(hidden))]
pub fn complete<I: Clone, O, E: ParseError<I>, F>(mut f: F) -> impl FnMut(I) -> IResult<I, O, E>
where
F: Parser<I, O, E>,
{
move |input: I| {
let i = input.clone();
match f.parse_next(input) {
Err(ErrMode::Incomplete(_)) => Err(ErrMode::from_error_kind(i, ErrorKind::Complete)),
rest => rest,
}
}
}
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct CompleteErr<F> {
f: F,
}
impl<F> CompleteErr<F> {
#[inline(always)]
pub(crate) fn new(f: F) -> Self {
Self { f }
}
}
impl<F, I, O, E> Parser<I, O, E> for CompleteErr<F>
where
I: Stream,
F: Parser<I, O, E>,
E: ParseError<I>,
{
fn parse_next(&mut self, input: I) -> IResult<I, O, E> {
trace("complete_err", |input: I| {
let i = input.clone();
match (self.f).parse_next(input) {
Err(ErrMode::Incomplete(_)) => {
Err(ErrMode::from_error_kind(i, ErrorKind::Complete))
}
rest => rest,
}
})(input)
}
}
#[deprecated(
since = "0.1.0",
note = "Replaced with `eof` or `FinishIResult::finish`"
)]
#[cfg_attr(feature = "unstable-doc", doc(hidden))]
pub fn all_consuming<I, O, E: ParseError<I>, F>(mut f: F) -> impl FnMut(I) -> IResult<I, O, E>
where
I: Stream,
F: Parser<I, O, E>,
{
move |input: I| {
let (input, res) = f.parse_next(input)?;
if input.eof_offset() == 0 {
Ok((input, res))
} else {
Err(ErrMode::from_error_kind(input, ErrorKind::Eof))
}
}
}
#[deprecated(since = "0.1.0", note = "Replaced with `Parser::verify")]
#[cfg_attr(feature = "unstable-doc", doc(hidden))]
pub fn verify<I: Clone, O1, O2, E: ParseError<I>, F, G>(
mut first: F,
second: G,
) -> impl FnMut(I) -> IResult<I, O1, E>
where
F: Parser<I, O1, E>,
G: Fn(&O2) -> bool,
O1: Borrow<O2>,
O2: ?Sized,
{
move |input: I| {
let i = input.clone();
let (input, o) = first.parse_next(input)?;
if second(o.borrow()) {
Ok((input, o))
} else {
Err(ErrMode::from_error_kind(i, ErrorKind::Verify))
}
}
}
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct Verify<F, G, O2: ?Sized> {
first: F,
second: G,
phantom: core::marker::PhantomData<O2>,
}
impl<F, G, O2: ?Sized> Verify<F, G, O2> {
#[inline(always)]
pub(crate) fn new(first: F, second: G) -> Self {
Self {
first,
second,
phantom: Default::default(),
}
}
}
impl<I, O1, O2, E, F, G> Parser<I, O1, E> for Verify<F, G, O2>
where
I: Clone,
E: ParseError<I>,
F: Parser<I, O1, E>,
G: Fn(&O2) -> bool,
O1: Borrow<O2>,
O2: ?Sized,
{
fn parse_next(&mut self, input: I) -> IResult<I, O1, E> {
let i = input.clone();
let (input, o) = (self.first).parse_next(input)?;
let res = if (self.second)(o.borrow()) {
Ok((input, o))
} else {
Err(ErrMode::from_error_kind(i, ErrorKind::Verify))
};
trace_result("verify", &res);
res
}
}
#[deprecated(since = "0.1.0", note = "Replaced with `Parser::value")]
#[cfg_attr(feature = "unstable-doc", doc(hidden))]
pub fn value<I, O1: Clone, O2, E: ParseError<I>, F>(
val: O1,
mut parser: F,
) -> impl FnMut(I) -> IResult<I, O1, E>
where
F: Parser<I, O2, E>,
{
move |input: I| parser.parse_next(input).map(|(i, _)| (i, val.clone()))
}
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct Value<F, O1, O2> {
parser: F,
val: O2,
phantom: core::marker::PhantomData<O1>,
}
impl<F, O1, O2> Value<F, O1, O2> {
#[inline(always)]
pub(crate) fn new(parser: F, val: O2) -> Self {
Self {
parser,
val,
phantom: Default::default(),
}
}
}
impl<I, O1, O2: Clone, E: ParseError<I>, F: Parser<I, O1, E>> Parser<I, O2, E>
for Value<F, O1, O2>
{
fn parse_next(&mut self, input: I) -> IResult<I, O2, E> {
(self.parser)
.parse_next(input)
.map(|(i, _)| (i, self.val.clone()))
}
}
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct Void<F, O> {
parser: F,
phantom: core::marker::PhantomData<O>,
}
impl<F, O> Void<F, O> {
#[inline(always)]
pub(crate) fn new(parser: F) -> Self {
Self {
parser,
phantom: Default::default(),
}
}
}
impl<I, O, E: ParseError<I>, F: Parser<I, O, E>> Parser<I, (), E> for Void<F, O> {
fn parse_next(&mut self, input: I) -> IResult<I, (), E> {
(self.parser).parse_next(input).map(|(i, _)| (i, ()))
}
}
pub fn not<I: Stream, O, E: ParseError<I>, F>(mut parser: F) -> impl FnMut(I) -> IResult<I, (), E>
where
F: Parser<I, O, E>,
{
trace("not", move |input: I| {
let i = input.clone();
match parser.parse_next(input) {
Ok(_) => Err(ErrMode::from_error_kind(i, ErrorKind::Not)),
Err(ErrMode::Backtrack(_)) => Ok((i, ())),
Err(e) => Err(e),
}
})
}
#[deprecated(since = "0.1.0", note = "Replaced with `Parser::recognize")]
#[cfg_attr(feature = "unstable-doc", doc(hidden))]
pub fn recognize<I, O, E: ParseError<I>, F>(
mut parser: F,
) -> impl FnMut(I) -> IResult<I, <I as Stream>::Slice, E>
where
I: Stream + Offset,
F: Parser<I, O, E>,
{
move |input: I| {
let i = input.clone();
match parser.parse_next(i) {
Ok((i, _)) => {
let offset = input.offset_to(&i);
Ok(input.next_slice(offset))
}
Err(e) => Err(e),
}
}
}
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct Recognize<F, O> {
parser: F,
o: core::marker::PhantomData<O>,
}
impl<F, O> Recognize<F, O> {
#[inline(always)]
pub(crate) fn new(parser: F) -> Self {
Self {
parser,
o: Default::default(),
}
}
}
impl<I, O, E, F> Parser<I, <I as Stream>::Slice, E> for Recognize<F, O>
where
I: Stream + Offset,
E: ParseError<I>,
F: Parser<I, O, E>,
{
fn parse_next(&mut self, input: I) -> IResult<I, <I as Stream>::Slice, E> {
let i = input.clone();
match (self.parser).parse_next(i) {
Ok((i, _)) => {
let offset = input.offset_to(&i);
Ok(input.next_slice(offset))
}
Err(e) => Err(e),
}
}
}
#[deprecated(
since = "0.1.0",
note = "Replaced with `Parser::with_recognized (output ordering is changed)"
)]
#[cfg_attr(feature = "unstable-doc", doc(hidden))]
pub fn consumed<I, O, F, E>(
mut parser: F,
) -> impl FnMut(I) -> IResult<I, (<I as Stream>::Slice, O), E>
where
I: Stream + Offset,
E: ParseError<I>,
F: Parser<I, O, E>,
{
move |input: I| {
let i = input.clone();
match parser.parse_next(i) {
Ok((remaining, result)) => {
let offset = input.offset_to(&remaining);
let (remaining, recognized) = input.next_slice(offset);
Ok((remaining, (recognized, result)))
}
Err(e) => Err(e),
}
}
}
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct WithRecognized<F, O> {
parser: F,
o: core::marker::PhantomData<O>,
}
impl<F, O> WithRecognized<F, O> {
#[inline(always)]
pub(crate) fn new(parser: F) -> Self {
Self {
parser,
o: Default::default(),
}
}
}
impl<I, O, E, F> Parser<I, (O, <I as Stream>::Slice), E> for WithRecognized<F, O>
where
I: Stream + Offset,
E: ParseError<I>,
F: Parser<I, O, E>,
{
fn parse_next(&mut self, input: I) -> IResult<I, (O, <I as Stream>::Slice), E> {
let i = input.clone();
match (self.parser).parse_next(i) {
Ok((remaining, result)) => {
let offset = input.offset_to(&remaining);
let (remaining, recognized) = input.next_slice(offset);
Ok((remaining, (result, recognized)))
}
Err(e) => Err(e),
}
}
}
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct Span<F, O> {
parser: F,
o: core::marker::PhantomData<O>,
}
impl<F, O> Span<F, O> {
#[inline(always)]
pub(crate) fn new(parser: F) -> Self {
Self {
parser,
o: Default::default(),
}
}
}
impl<I, O, E, F> Parser<I, Range<usize>, E> for Span<F, O>
where
I: Clone + Location,
E: ParseError<I>,
F: Parser<I, O, E>,
{
fn parse_next(&mut self, input: I) -> IResult<I, Range<usize>, E> {
let start = input.location();
self.parser.parse_next(input).map(move |(remaining, _)| {
let end = remaining.location();
(remaining, (start..end))
})
}
}
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct WithSpan<F, O> {
parser: F,
o: core::marker::PhantomData<O>,
}
impl<F, O> WithSpan<F, O> {
#[inline(always)]
pub(crate) fn new(parser: F) -> Self {
Self {
parser,
o: Default::default(),
}
}
}
impl<I, O, E, F> Parser<I, (O, Range<usize>), E> for WithSpan<F, O>
where
I: Clone + Location,
E: ParseError<I>,
F: Parser<I, O, E>,
{
fn parse_next(&mut self, input: I) -> IResult<I, (O, Range<usize>), E> {
let start = input.location();
self.parser
.parse_next(input)
.map(move |(remaining, output)| {
let end = remaining.location();
(remaining, (output, (start..end)))
})
}
}
pub fn cut_err<I, O, E: ParseError<I>, F>(mut parser: F) -> impl FnMut(I) -> IResult<I, O, E>
where
I: Stream,
F: Parser<I, O, E>,
{
trace("cut_err", move |input: I| {
parser.parse_next(input).map_err(|e| e.cut())
})
}
#[deprecated(since = "0.3.0", note = "Replaced with `cut_err`")]
#[cfg_attr(feature = "unstable-doc", doc(hidden))]
pub fn cut<I, O, E: ParseError<I>, F>(parser: F) -> impl FnMut(I) -> IResult<I, O, E>
where
I: Stream,
F: Parser<I, O, E>,
{
cut_err(parser)
}
pub fn backtrack_err<I, O, E: ParseError<I>, F>(mut parser: F) -> impl FnMut(I) -> IResult<I, O, E>
where
I: Stream,
F: Parser<I, O, E>,
{
trace("backtrack_err", move |input: I| {
parser.parse_next(input).map_err(|e| e.backtrack())
})
}
#[track_caller]
pub fn todo<I, O, E>(input: I) -> IResult<I, O, E>
where
I: Stream,
{
#![allow(clippy::todo)]
trace("todo", move |_input: I| todo!("unimplemented parse"))(input)
}
#[deprecated(
since = "0.1.0",
note = "Replaced with `Parser::output_into` and `Parser::err_into`"
)]
#[cfg_attr(feature = "unstable-doc", doc(hidden))]
pub fn into<I, O1, O2, E1, E2, F>(mut parser: F) -> impl FnMut(I) -> IResult<I, O2, E2>
where
O1: convert::Into<O2>,
E1: convert::Into<E2>,
E1: ParseError<I>,
E2: ParseError<I>,
F: Parser<I, O1, E1>,
{
move |input: I| match parser.parse_next(input) {
Ok((i, o)) => Ok((i, o.into())),
Err(ErrMode::Backtrack(e)) => Err(ErrMode::Backtrack(e.into())),
Err(ErrMode::Cut(e)) => Err(ErrMode::Cut(e.into())),
Err(ErrMode::Incomplete(e)) => Err(ErrMode::Incomplete(e)),
}
}
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct OutputInto<F, O1, O2>
where
O1: Into<O2>,
{
f: F,
phantom_out1: core::marker::PhantomData<O1>,
phantom_out2: core::marker::PhantomData<O2>,
}
impl<F, O1, O2> OutputInto<F, O1, O2>
where
O1: Into<O2>,
{
#[inline(always)]
pub(crate) fn new(f: F) -> Self {
Self {
f,
phantom_out1: Default::default(),
phantom_out2: Default::default(),
}
}
}
impl<I: Clone, O1, O2, E, F: Parser<I, O1, E>> Parser<I, O2, E> for OutputInto<F, O1, O2>
where
O1: Into<O2>,
{
fn parse_next(&mut self, i: I) -> IResult<I, O2, E> {
match self.f.parse_next(i) {
Ok((i, o)) => Ok((i, o.into())),
Err(err) => Err(err),
}
}
}
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct ErrInto<F, E1, E2>
where
E1: Into<E2>,
{
f: F,
phantom_err1: core::marker::PhantomData<E1>,
phantom_err2: core::marker::PhantomData<E2>,
}
impl<F, E1, E2> ErrInto<F, E1, E2>
where
E1: Into<E2>,
{
#[inline(always)]
pub(crate) fn new(f: F) -> Self {
Self {
f,
phantom_err1: Default::default(),
phantom_err2: Default::default(),
}
}
}
impl<I: Clone, O, E1, E2: crate::error::ParseError<I>, F: Parser<I, O, E1>> Parser<I, O, E2>
for ErrInto<F, E1, E2>
where
E1: Into<E2>,
{
fn parse_next(&mut self, i: I) -> IResult<I, O, E2> {
match self.f.parse_next(i) {
Ok(ok) => Ok(ok),
Err(ErrMode::Backtrack(e)) => Err(ErrMode::Backtrack(e.into())),
Err(ErrMode::Cut(e)) => Err(ErrMode::Cut(e.into())),
Err(ErrMode::Incomplete(e)) => Err(ErrMode::Incomplete(e)),
}
}
}
pub fn iterator<I, Output, Error, F>(input: I, f: F) -> ParserIterator<I, Output, Error, F>
where
F: Parser<I, Output, Error>,
Error: ParseError<I>,
{
ParserIterator {
iterator: f,
input,
output: Default::default(),
state: Some(State::Running),
}
}
pub struct ParserIterator<I, O, E, F> {
iterator: F,
input: I,
output: core::marker::PhantomData<O>,
state: Option<State<E>>,
}
impl<I: Clone, O, E, F> ParserIterator<I, O, E, F> {
pub fn finish(mut self) -> IResult<I, (), E> {
match self.state.take().unwrap() {
State::Running | State::Done => Ok((self.input, ())),
State::Failure(e) => Err(ErrMode::Cut(e)),
State::Incomplete(i) => Err(ErrMode::Incomplete(i)),
}
}
}
impl<'a, I, O, E, F> core::iter::Iterator for &'a mut ParserIterator<I, O, E, F>
where
F: Parser<I, O, E>,
I: Clone,
{
type Item = O;
fn next(&mut self) -> Option<Self::Item> {
if let State::Running = self.state.take().unwrap() {
let input = self.input.clone();
match self.iterator.parse_next(input) {
Ok((i, o)) => {
self.input = i;
self.state = Some(State::Running);
Some(o)
}
Err(ErrMode::Backtrack(_)) => {
self.state = Some(State::Done);
None
}
Err(ErrMode::Cut(e)) => {
self.state = Some(State::Failure(e));
None
}
Err(ErrMode::Incomplete(i)) => {
self.state = Some(State::Incomplete(i));
None
}
}
} else {
None
}
}
}
enum State<E> {
Running,
Done,
Failure(E),
Incomplete(Needed),
}
#[doc(alias = "value")]
#[doc(alias = "empty")]
pub fn success<I: Stream, O: Clone, E: ParseError<I>>(val: O) -> impl FnMut(I) -> IResult<I, O, E> {
trace("success", move |input: I| Ok((input, val.clone())))
}
#[doc(alias = "unexpected")]
pub fn fail<I: Stream, O, E: ParseError<I>>(i: I) -> IResult<I, O, E> {
trace("fail", |i| {
Err(ErrMode::from_error_kind(i, ErrorKind::Fail))
})(i)
}
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct Context<F, O, C: Clone + crate::lib::std::fmt::Debug> {
f: F,
context: C,
phantom: core::marker::PhantomData<O>,
}
impl<F, O, C: Clone + crate::lib::std::fmt::Debug> Context<F, O, C> {
#[inline(always)]
pub(crate) fn new(f: F, context: C) -> Self {
Self {
f,
context,
phantom: Default::default(),
}
}
}
impl<I, O, E, F, C> Parser<I, O, E> for Context<F, O, C>
where
I: Stream,
C: Clone + crate::lib::std::fmt::Debug,
E: ContextError<I, C>,
F: Parser<I, O, E>,
{
fn parse_next(&mut self, i: I) -> IResult<I, O, E> {
#[cfg(feature = "debug")]
let name = format!("context={:?}", self.context);
#[cfg(not(feature = "debug"))]
let name = "context";
trace(name, move |i: I| {
(self.f)
.parse_next(i.clone())
.map_err(|err| err.map(|err| err.add_context(i, self.context.clone())))
})(i)
}
}