use crate::error::{AddContext, ErrMode, ErrorKind, FromExternalError, ParserError}; use crate::lib::std::borrow::Borrow; use crate::lib::std::ops::Range; use crate::stream::StreamIsPartial; use crate::stream::{Location, Stream}; use crate::trace::trace; use crate::trace::trace_result; use crate::*; /// Implementation of [`Parser::by_ref`][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: Fn(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: Fn(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: Fn(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: Fn(&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: Fn(&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: Fn(&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::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) } }