//! Opaque implementations of [`Parser`] use crate::combinator::trace; use crate::combinator::trace_result; use crate::combinator::DisplayDebug; #[cfg(feature = "unstable-recover")] #[cfg(feature = "std")] use crate::error::FromRecoverableError; use crate::error::{AddContext, ErrMode, ErrorKind, FromExternalError, ParserError}; use crate::lib::std::borrow::Borrow; use crate::lib::std::ops::Range; #[cfg(feature = "unstable-recover")] #[cfg(feature = "std")] use crate::stream::Recover; use crate::stream::StreamIsPartial; use crate::stream::{Location, Stream}; use crate::*; /// [`Parser`] implementation for [`Parser::by_ref`] pub struct ByRef<'p, P> { pub(crate) p: &'p mut P, } impl Parser for ByRef<'_, P> where P: Parser, { #[inline(always)] fn parse_next(&mut self, i: &mut I) -> PResult { self.p.parse_next(i) } } /// [`Parser`] implementation for [`Parser::map`] pub struct Map where F: Parser, G: FnMut(O) -> O2, { pub(crate) parser: F, pub(crate) map: G, pub(crate) i: core::marker::PhantomData, pub(crate) o: core::marker::PhantomData, pub(crate) o2: core::marker::PhantomData, pub(crate) e: core::marker::PhantomData, } impl Parser for Map where F: Parser, G: FnMut(O) -> O2, { #[inline] fn parse_next(&mut self, i: &mut I) -> PResult { match self.parser.parse_next(i) { Err(e) => Err(e), Ok(o) => Ok((self.map)(o)), } } } /// [`Parser`] implementation for [`Parser::try_map`] pub struct TryMap where F: Parser, G: FnMut(O) -> Result, I: Stream, E: FromExternalError, { pub(crate) parser: F, pub(crate) map: G, pub(crate) i: core::marker::PhantomData, pub(crate) o: core::marker::PhantomData, pub(crate) o2: core::marker::PhantomData, pub(crate) e: core::marker::PhantomData, pub(crate) e2: core::marker::PhantomData, } impl Parser for TryMap where F: Parser, G: FnMut(O) -> Result, I: Stream, E: FromExternalError, { #[inline] fn parse_next(&mut self, input: &mut I) -> PResult { let start = input.checkpoint(); let o = self.parser.parse_next(input)?; let res = (self.map)(o).map_err(|err| { input.reset(&start); ErrMode::from_external_error(input, ErrorKind::Verify, err) }); trace_result("verify", &res); res } } /// [`Parser`] implementation for [`Parser::verify_map`] pub struct VerifyMap where F: Parser, G: FnMut(O) -> Option, I: Stream, E: ParserError, { pub(crate) parser: F, pub(crate) map: G, pub(crate) i: core::marker::PhantomData, pub(crate) o: core::marker::PhantomData, pub(crate) o2: core::marker::PhantomData, pub(crate) e: core::marker::PhantomData, } impl Parser for VerifyMap where F: Parser, G: FnMut(O) -> Option, I: Stream, E: ParserError, { #[inline] fn parse_next(&mut self, input: &mut I) -> PResult { let start = input.checkpoint(); let o = self.parser.parse_next(input)?; let res = (self.map)(o).ok_or_else(|| { input.reset(&start); ErrMode::from_error_kind(input, ErrorKind::Verify) }); trace_result("verify", &res); res } } /// [`Parser`] implementation for [`Parser::and_then`] pub struct AndThen where F: Parser, G: Parser, O: StreamIsPartial, I: Stream, { pub(crate) outer: F, pub(crate) inner: G, pub(crate) i: core::marker::PhantomData, pub(crate) o: core::marker::PhantomData, pub(crate) o2: core::marker::PhantomData, pub(crate) e: core::marker::PhantomData, } impl Parser for AndThen where F: Parser, G: Parser, O: StreamIsPartial, I: Stream, { #[inline(always)] fn parse_next(&mut self, i: &mut I) -> PResult { let start = i.checkpoint(); let mut o = self.outer.parse_next(i)?; let _ = o.complete(); let o2 = self.inner.parse_next(&mut o).map_err(|err| { i.reset(&start); err })?; Ok(o2) } } /// [`Parser`] implementation for [`Parser::parse_to`] pub struct ParseTo where P: Parser, I: Stream, O: crate::stream::ParseSlice, E: ParserError, { pub(crate) p: P, pub(crate) i: core::marker::PhantomData, pub(crate) o: core::marker::PhantomData, pub(crate) o2: core::marker::PhantomData, pub(crate) e: core::marker::PhantomData, } impl Parser for ParseTo where P: Parser, I: Stream, O: crate::stream::ParseSlice, E: ParserError, { #[inline] fn parse_next(&mut self, i: &mut I) -> PResult { let start = i.checkpoint(); let o = self.p.parse_next(i)?; let res = o.parse_slice().ok_or_else(|| { i.reset(&start); ErrMode::from_error_kind(i, ErrorKind::Verify) }); trace_result("verify", &res); res } } /// [`Parser`] implementation for [`Parser::flat_map`] pub struct FlatMap where F: Parser, G: FnMut(O) -> H, H: Parser, { pub(crate) f: F, pub(crate) g: G, pub(crate) h: core::marker::PhantomData, pub(crate) i: core::marker::PhantomData, pub(crate) o: core::marker::PhantomData, pub(crate) o2: core::marker::PhantomData, pub(crate) e: core::marker::PhantomData, } impl Parser for FlatMap where F: Parser, G: FnMut(O) -> H, H: Parser, { #[inline(always)] fn parse_next(&mut self, i: &mut I) -> PResult { let o = self.f.parse_next(i)?; (self.g)(o).parse_next(i) } } /// [`Parser`] implementation for [`Parser::complete_err`] pub struct CompleteErr { pub(crate) f: F, } impl Parser for CompleteErr where I: Stream, F: Parser, E: ParserError, { #[inline] fn parse_next(&mut self, input: &mut I) -> PResult { trace("complete_err", |input: &mut I| { match (self.f).parse_next(input) { Err(ErrMode::Incomplete(_)) => { Err(ErrMode::from_error_kind(input, ErrorKind::Complete)) } rest => rest, } }) .parse_next(input) } } /// [`Parser`] implementation for [`Parser::verify`] pub struct Verify where F: Parser, G: FnMut(&O2) -> bool, I: Stream, O: Borrow, O2: ?Sized, E: ParserError, { pub(crate) parser: F, pub(crate) filter: G, pub(crate) i: core::marker::PhantomData, pub(crate) o: core::marker::PhantomData, pub(crate) o2: core::marker::PhantomData, pub(crate) e: core::marker::PhantomData, } impl Parser for Verify where F: Parser, G: FnMut(&O2) -> bool, I: Stream, O: Borrow, O2: ?Sized, E: ParserError, { #[inline] fn parse_next(&mut self, input: &mut I) -> PResult { let start = input.checkpoint(); let o = self.parser.parse_next(input)?; let res = (self.filter)(o.borrow()).then_some(o).ok_or_else(|| { input.reset(&start); ErrMode::from_error_kind(input, ErrorKind::Verify) }); trace_result("verify", &res); res } } /// [`Parser`] implementation for [`Parser::value`] pub struct Value where F: Parser, O2: Clone, { pub(crate) parser: F, pub(crate) val: O2, pub(crate) i: core::marker::PhantomData, pub(crate) o: core::marker::PhantomData, pub(crate) e: core::marker::PhantomData, } impl Parser for Value where F: Parser, O2: Clone, { #[inline] fn parse_next(&mut self, input: &mut I) -> PResult { (self.parser).parse_next(input).map(|_| self.val.clone()) } } /// [`Parser`] implementation for [`Parser::default_value`] pub struct DefaultValue where F: Parser, O2: core::default::Default, { pub(crate) parser: F, pub(crate) o2: core::marker::PhantomData, pub(crate) i: core::marker::PhantomData, pub(crate) o: core::marker::PhantomData, pub(crate) e: core::marker::PhantomData, } impl Parser for DefaultValue where F: Parser, O2: core::default::Default, { #[inline] fn parse_next(&mut self, input: &mut I) -> PResult { (self.parser).parse_next(input).map(|_| O2::default()) } } /// [`Parser`] implementation for [`Parser::void`] pub struct Void where F: Parser, { pub(crate) parser: F, pub(crate) i: core::marker::PhantomData, pub(crate) o: core::marker::PhantomData, pub(crate) e: core::marker::PhantomData, } impl Parser for Void where F: Parser, { #[inline(always)] fn parse_next(&mut self, input: &mut I) -> PResult<(), E> { (self.parser).parse_next(input).map(|_| ()) } } /// Replaced with [`Take`] #[deprecated(since = "0.6.14", note = "Replaced with `Take`")] pub type Recognize = Take; /// [`Parser`] implementation for [`Parser::take`] pub struct Take where F: Parser, I: Stream, { pub(crate) parser: F, pub(crate) i: core::marker::PhantomData, pub(crate) o: core::marker::PhantomData, pub(crate) e: core::marker::PhantomData, } impl Parser::Slice, E> for Take where F: Parser, I: Stream, { #[inline] fn parse_next(&mut self, input: &mut I) -> PResult<::Slice, E> { let checkpoint = input.checkpoint(); match (self.parser).parse_next(input) { Ok(_) => { let offset = input.offset_from(&checkpoint); input.reset(&checkpoint); let taken = input.next_slice(offset); Ok(taken) } Err(e) => Err(e), } } } /// Replaced with [`WithTaken`] #[deprecated(since = "0.6.14", note = "Replaced with `WithTaken`")] pub type WithRecognized = WithTaken; /// [`Parser`] implementation for [`Parser::with_taken`] pub struct WithTaken where F: Parser, I: Stream, { pub(crate) parser: F, pub(crate) i: core::marker::PhantomData, pub(crate) o: core::marker::PhantomData, pub(crate) e: core::marker::PhantomData, } impl Parser::Slice), E> for WithTaken where F: Parser, I: Stream, { #[inline] fn parse_next(&mut self, input: &mut I) -> PResult<(O, ::Slice), E> { let checkpoint = input.checkpoint(); match (self.parser).parse_next(input) { Ok(result) => { let offset = input.offset_from(&checkpoint); input.reset(&checkpoint); let taken = input.next_slice(offset); Ok((result, taken)) } Err(e) => Err(e), } } } /// [`Parser`] implementation for [`Parser::span`] pub struct Span where F: Parser, I: Stream + Location, { pub(crate) parser: F, pub(crate) i: core::marker::PhantomData, pub(crate) o: core::marker::PhantomData, pub(crate) e: core::marker::PhantomData, } impl Parser, E> for Span where F: Parser, I: Stream + Location, { #[inline] fn parse_next(&mut self, input: &mut I) -> PResult, E> { let start = input.location(); self.parser.parse_next(input).map(move |_| { let end = input.location(); start..end }) } } /// [`Parser`] implementation for [`Parser::with_span`] pub struct WithSpan where F: Parser, I: Stream + Location, { pub(crate) parser: F, pub(crate) i: core::marker::PhantomData, pub(crate) o: core::marker::PhantomData, pub(crate) e: core::marker::PhantomData, } impl Parser), E> for WithSpan where F: Parser, I: Stream + Location, { #[inline] fn parse_next(&mut self, input: &mut I) -> PResult<(O, Range), E> { let start = input.location(); self.parser.parse_next(input).map(move |output| { let end = input.location(); (output, (start..end)) }) } } /// [`Parser`] implementation for [`Parser::output_into`] pub struct OutputInto where F: Parser, O: Into, { pub(crate) parser: F, pub(crate) i: core::marker::PhantomData, pub(crate) o: core::marker::PhantomData, pub(crate) o2: core::marker::PhantomData, pub(crate) e: core::marker::PhantomData, } impl Parser for OutputInto where F: Parser, O: Into, { #[inline] fn parse_next(&mut self, i: &mut I) -> PResult { self.parser.parse_next(i).map(|o| o.into()) } } /// [`Parser`] implementation for [`Parser::err_into`] pub struct ErrInto where F: Parser, E: Into, { pub(crate) parser: F, pub(crate) i: core::marker::PhantomData, pub(crate) o: core::marker::PhantomData, pub(crate) e: core::marker::PhantomData, pub(crate) e2: core::marker::PhantomData, } impl Parser for ErrInto where F: Parser, E: Into, { #[inline] fn parse_next(&mut self, i: &mut I) -> PResult { self.parser .parse_next(i) .map_err(|err| err.map(|e| e.into())) } } /// [`Parser`] implementation for [`Parser::context`] pub struct Context where F: Parser, I: Stream, E: AddContext, C: Clone + crate::lib::std::fmt::Debug, { pub(crate) parser: F, pub(crate) context: C, pub(crate) i: core::marker::PhantomData, pub(crate) o: core::marker::PhantomData, pub(crate) e: core::marker::PhantomData, } impl Parser for Context where F: Parser, I: Stream, E: AddContext, C: Clone + crate::lib::std::fmt::Debug, { #[inline] fn parse_next(&mut self, i: &mut I) -> PResult { let context = self.context.clone(); trace(DisplayDebug(self.context.clone()), move |i: &mut I| { let start = i.checkpoint(); (self.parser) .parse_next(i) .map_err(|err| err.add_context(i, &start, context.clone())) }) .parse_next(i) } } /// [`Parser`] implementation for [`Parser::retry_after`] #[cfg(feature = "unstable-recover")] #[cfg(feature = "std")] pub struct RetryAfter where P: Parser, R: Parser, I: Stream, I: Recover, E: FromRecoverableError, { pub(crate) parser: P, pub(crate) recover: R, pub(crate) i: core::marker::PhantomData, pub(crate) o: core::marker::PhantomData, pub(crate) e: core::marker::PhantomData, } #[cfg(feature = "unstable-recover")] #[cfg(feature = "std")] impl Parser for RetryAfter where P: Parser, R: Parser, I: Stream, I: Recover, E: FromRecoverableError, { #[inline(always)] fn parse_next(&mut self, i: &mut I) -> PResult { if I::is_recovery_supported() { retry_after_inner(&mut self.parser, &mut self.recover, i) } else { self.parser.parse_next(i) } } } #[cfg(feature = "unstable-recover")] #[cfg(feature = "std")] fn retry_after_inner(parser: &mut P, recover: &mut R, i: &mut I) -> PResult where P: Parser, R: Parser, I: Stream, I: Recover, E: FromRecoverableError, { loop { let token_start = i.checkpoint(); let mut err = match parser.parse_next(i) { Ok(o) => { return Ok(o); } Err(ErrMode::Incomplete(e)) => return Err(ErrMode::Incomplete(e)), Err(err) => err, }; let err_start = i.checkpoint(); let err_start_eof_offset = i.eof_offset(); if recover.parse_next(i).is_ok() { let i_eof_offset = i.eof_offset(); if err_start_eof_offset == i_eof_offset { // Didn't advance so bubble the error up } else if let Err(err_) = i.record_err(&token_start, &err_start, err) { err = err_; } else { continue; } } i.reset(&err_start); err = err.map(|err| E::from_recoverable_error(&token_start, &err_start, i, err)); return Err(err); } } /// [`Parser`] implementation for [`Parser::resume_after`] #[cfg(feature = "unstable-recover")] #[cfg(feature = "std")] pub struct ResumeAfter where P: Parser, R: Parser, I: Stream, I: Recover, E: FromRecoverableError, { pub(crate) parser: P, pub(crate) recover: R, pub(crate) i: core::marker::PhantomData, pub(crate) o: core::marker::PhantomData, pub(crate) e: core::marker::PhantomData, } #[cfg(feature = "unstable-recover")] #[cfg(feature = "std")] impl Parser, E> for ResumeAfter where P: Parser, R: Parser, I: Stream, I: Recover, E: FromRecoverableError, { #[inline(always)] fn parse_next(&mut self, i: &mut I) -> PResult, E> { if I::is_recovery_supported() { resume_after_inner(&mut self.parser, &mut self.recover, i) } else { self.parser.parse_next(i).map(Some) } } } #[cfg(feature = "unstable-recover")] #[cfg(feature = "std")] fn resume_after_inner( parser: &mut P, recover: &mut R, i: &mut I, ) -> PResult, E> where P: Parser, R: Parser, I: Stream, I: Recover, E: FromRecoverableError, { let token_start = i.checkpoint(); let mut err = match parser.parse_next(i) { Ok(o) => { return Ok(Some(o)); } Err(ErrMode::Incomplete(e)) => return Err(ErrMode::Incomplete(e)), Err(err) => err, }; let err_start = i.checkpoint(); if recover.parse_next(i).is_ok() { if let Err(err_) = i.record_err(&token_start, &err_start, err) { err = err_; } else { return Ok(None); } } i.reset(&err_start); err = err.map(|err| E::from_recoverable_error(&token_start, &err_start, i, err)); Err(err) }