use crate::combinator::trace; use crate::combinator::trace_result; #[cfg(feature = "unstable-recover")] 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")] use crate::stream::Recover; use crate::stream::StreamIsPartial; use crate::stream::{Location, Stream}; use crate::*; /// Implementation of [`Parser::by_ref`] #[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 for ByRef<'p, P> where P: Parser, { #[inline(always)] fn parse_next(&mut self, i: &mut I) -> PResult { self.p.parse_next(i) } } /// Implementation of [`Parser::map`] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pub struct Map where F: Parser, G: FnMut(O) -> O2, { parser: F, map: G, i: core::marker::PhantomData, o: core::marker::PhantomData, o2: core::marker::PhantomData, e: core::marker::PhantomData, } impl Map where F: Parser, G: FnMut(O) -> O2, { #[inline(always)] pub(crate) fn new(parser: F, map: G) -> Self { Self { parser, map, i: Default::default(), o: Default::default(), o2: Default::default(), e: Default::default(), } } } 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)), } } } /// Implementation of [`Parser::try_map`] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pub struct TryMap where F: Parser, G: FnMut(O) -> Result, I: Stream, E: FromExternalError, { parser: F, map: G, i: core::marker::PhantomData, o: core::marker::PhantomData, o2: core::marker::PhantomData, e: core::marker::PhantomData, e2: core::marker::PhantomData, } impl TryMap where F: Parser, G: FnMut(O) -> Result, I: Stream, E: FromExternalError, { #[inline(always)] pub(crate) fn new(parser: F, map: G) -> Self { Self { parser, map, i: Default::default(), o: Default::default(), o2: Default::default(), e: Default::default(), e2: Default::default(), } } } 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 } } /// Implementation of [`Parser::verify_map`] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pub struct VerifyMap where F: Parser, G: FnMut(O) -> Option, I: Stream, E: ParserError, { parser: F, map: G, i: core::marker::PhantomData, o: core::marker::PhantomData, o2: core::marker::PhantomData, e: core::marker::PhantomData, } impl VerifyMap where F: Parser, G: FnMut(O) -> Option, I: Stream, E: ParserError, { #[inline(always)] pub(crate) fn new(parser: F, map: G) -> Self { Self { parser, map, i: Default::default(), o: Default::default(), o2: Default::default(), e: Default::default(), } } } 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 } } /// Implementation of [`Parser::and_then`] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pub struct AndThen where F: Parser, G: Parser, O: StreamIsPartial, I: Stream, { outer: F, inner: G, i: core::marker::PhantomData, o: core::marker::PhantomData, o2: core::marker::PhantomData, e: core::marker::PhantomData, } impl AndThen where F: Parser, G: Parser, O: StreamIsPartial, I: Stream, { #[inline(always)] pub(crate) fn new(outer: F, inner: G) -> Self { Self { outer, inner, i: Default::default(), o: Default::default(), o2: Default::default(), e: Default::default(), } } } 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) } } /// Implementation of [`Parser::parse_to`] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pub struct ParseTo where P: Parser, I: Stream, O: crate::stream::ParseSlice, E: ParserError, { p: P, i: core::marker::PhantomData, o: core::marker::PhantomData, o2: core::marker::PhantomData, e: core::marker::PhantomData, } impl ParseTo where P: Parser, I: Stream, O: crate::stream::ParseSlice, E: ParserError, { #[inline(always)] pub(crate) fn new(p: P) -> Self { Self { p, i: Default::default(), o: Default::default(), o2: Default::default(), e: Default::default(), } } } 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 } } /// Implementation of [`Parser::flat_map`] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pub struct FlatMap where F: Parser, G: FnMut(O) -> H, H: Parser, { f: F, g: G, h: core::marker::PhantomData, i: core::marker::PhantomData, o: core::marker::PhantomData, o2: core::marker::PhantomData, e: core::marker::PhantomData, } impl FlatMap where F: Parser, G: FnMut(O) -> H, H: Parser, { #[inline(always)] pub(crate) fn new(f: F, g: G) -> Self { Self { f, g, h: Default::default(), i: Default::default(), o: Default::default(), o2: Default::default(), e: Default::default(), } } } 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) } } /// Implementation of [`Parser::complete_err`] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pub struct CompleteErr { f: F, } impl CompleteErr { #[inline(always)] pub(crate) fn new(f: F) -> Self { Self { 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) } } /// Implementation of [`Parser::verify`] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pub struct Verify where F: Parser, G: FnMut(&O2) -> bool, I: Stream, O: Borrow, O2: ?Sized, E: ParserError, { parser: F, filter: G, i: core::marker::PhantomData, o: core::marker::PhantomData, o2: core::marker::PhantomData, e: core::marker::PhantomData, } impl Verify where F: Parser, G: FnMut(&O2) -> bool, I: Stream, O: Borrow, O2: ?Sized, E: ParserError, { #[inline(always)] pub(crate) fn new(parser: F, filter: G) -> Self { Self { parser, filter, i: Default::default(), o: Default::default(), o2: Default::default(), e: Default::default(), } } } 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 } } /// Implementation of [`Parser::value`] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pub struct Value where F: Parser, O2: Clone, { parser: F, val: O2, i: core::marker::PhantomData, o: core::marker::PhantomData, e: core::marker::PhantomData, } impl Value where F: Parser, O2: Clone, { #[inline(always)] pub(crate) fn new(parser: F, val: O2) -> Self { Self { parser, val, i: Default::default(), o: Default::default(), e: Default::default(), } } } 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()) } } /// Implementation of [`Parser::default_value`] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pub struct DefaultValue where F: Parser, O2: core::default::Default, { parser: F, o2: core::marker::PhantomData, i: core::marker::PhantomData, o: core::marker::PhantomData, e: core::marker::PhantomData, } impl DefaultValue where F: Parser, O2: core::default::Default, { #[inline(always)] pub(crate) fn new(parser: F) -> Self { Self { parser, o2: Default::default(), i: Default::default(), o: Default::default(), e: Default::default(), } } } 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()) } } /// Implementation of [`Parser::void`] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pub struct Void where F: Parser, { parser: F, i: core::marker::PhantomData, o: core::marker::PhantomData, e: core::marker::PhantomData, } impl Void where F: Parser, { #[inline(always)] pub(crate) fn new(parser: F) -> Self { Self { parser, i: Default::default(), o: Default::default(), e: Default::default(), } } } 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(|_| ()) } } /// Implementation of [`Parser::recognize`] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pub struct Recognize where F: Parser, I: Stream, { parser: F, i: core::marker::PhantomData, o: core::marker::PhantomData, e: core::marker::PhantomData, } impl Recognize where F: Parser, I: Stream, { #[inline(always)] pub(crate) fn new(parser: F) -> Self { Self { parser, i: Default::default(), o: Default::default(), e: Default::default(), } } } impl Parser::Slice, E> for Recognize 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 recognized = input.next_slice(offset); Ok(recognized) } Err(e) => Err(e), } } } /// Implementation of [`Parser::with_recognized`] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pub struct WithRecognized where F: Parser, I: Stream, { parser: F, i: core::marker::PhantomData, o: core::marker::PhantomData, e: core::marker::PhantomData, } impl WithRecognized where F: Parser, I: Stream, { #[inline(always)] pub(crate) fn new(parser: F) -> Self { Self { parser, i: Default::default(), o: Default::default(), e: Default::default(), } } } impl Parser::Slice), E> for WithRecognized 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 recognized = input.next_slice(offset); Ok((result, recognized)) } Err(e) => Err(e), } } } /// Implementation of [`Parser::span`] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pub struct Span where F: Parser, I: Stream + Location, { parser: F, i: core::marker::PhantomData, o: core::marker::PhantomData, e: core::marker::PhantomData, } impl Span where F: Parser, I: Stream + Location, { #[inline(always)] pub(crate) fn new(parser: F) -> Self { Self { parser, i: Default::default(), o: Default::default(), e: Default::default(), } } } 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 }) } } /// Implementation of [`Parser::with_span`] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pub struct WithSpan where F: Parser, I: Stream + Location, { parser: F, i: core::marker::PhantomData, o: core::marker::PhantomData, e: core::marker::PhantomData, } impl WithSpan where F: Parser, I: Stream + Location, { #[inline(always)] pub(crate) fn new(parser: F) -> Self { Self { parser, i: Default::default(), o: Default::default(), e: Default::default(), } } } 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)) }) } } /// Implementation of [`Parser::output_into`] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pub struct OutputInto where F: Parser, O: Into, { parser: F, i: core::marker::PhantomData, o: core::marker::PhantomData, o2: core::marker::PhantomData, e: core::marker::PhantomData, } impl OutputInto where F: Parser, O: Into, { #[inline(always)] pub(crate) fn new(parser: F) -> Self { Self { parser, i: Default::default(), o: Default::default(), o2: Default::default(), e: Default::default(), } } } 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()) } } /// Implementation of [`Parser::err_into`] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pub struct ErrInto where F: Parser, E: Into, { parser: F, i: core::marker::PhantomData, o: core::marker::PhantomData, e: core::marker::PhantomData, e2: core::marker::PhantomData, } impl ErrInto where F: Parser, E: Into, { #[inline(always)] pub(crate) fn new(parser: F) -> Self { Self { parser, i: Default::default(), o: Default::default(), e: Default::default(), e2: Default::default(), } } } impl Parser for ErrInto where F: Parser, E: Into, { #[inline] fn parse_next(&mut self, i: &mut I) -> PResult { match self.parser.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)), } } } /// Implementation of [`Parser::context`] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pub struct Context where F: Parser, I: Stream, E: AddContext, C: Clone + crate::lib::std::fmt::Debug, { parser: F, context: C, i: core::marker::PhantomData, o: core::marker::PhantomData, e: core::marker::PhantomData, } impl Context where F: Parser, I: Stream, E: AddContext, C: Clone + crate::lib::std::fmt::Debug, { #[inline(always)] pub(crate) fn new(parser: F, context: C) -> Self { Self { parser, context, i: Default::default(), o: Default::default(), e: Default::default(), } } } 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 { #[cfg(feature = "debug")] let name = format!("context={:?}", self.context); #[cfg(not(feature = "debug"))] let name = "context"; trace(name, move |i: &mut I| { (self.parser) .parse_next(i) .map_err(|err| err.add_context(i, self.context.clone())) }) .parse_next(i) } } /// Implementation of [`Parser::retry_after`] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] #[cfg(feature = "unstable-recover")] pub struct RetryAfter where P: Parser, R: Parser, I: Stream, I: Recover, E: FromRecoverableError, { parser: P, recover: R, i: core::marker::PhantomData, o: core::marker::PhantomData, e: core::marker::PhantomData, } #[cfg(feature = "unstable-recover")] impl RetryAfter where P: Parser, R: Parser, I: Stream, I: Recover, E: FromRecoverableError, { #[inline(always)] pub(crate) fn new(parser: P, recover: R) -> Self { Self { parser, recover, i: Default::default(), o: Default::default(), e: Default::default(), } } } #[cfg(feature = "unstable-recover")] 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")] 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.clone()); err = err.map(|err| E::from_recoverable_error(&token_start, &err_start, i, err)); return Err(err); } } /// Implementation of [`Parser::resume_after`] #[cfg(feature = "unstable-recover")] #[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] pub struct ResumeAfter where P: Parser, R: Parser, I: Stream, I: Recover, E: FromRecoverableError, { parser: P, recover: R, i: core::marker::PhantomData, o: core::marker::PhantomData, e: core::marker::PhantomData, } #[cfg(feature = "unstable-recover")] impl ResumeAfter where P: Parser, R: Parser, I: Stream, I: Recover, E: FromRecoverableError, { #[inline(always)] pub(crate) fn new(parser: P, recover: R) -> Self { Self { parser, recover, i: Default::default(), o: Default::default(), e: Default::default(), } } } #[cfg(feature = "unstable-recover")] 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")] 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.clone()); err = err.map(|err| E::from_recoverable_error(&token_start, &err_start, i, err)); Err(err) }