//! A collection of both concrete parsers as well as parser combinators. //! //! Implements the [`Parser`] trait which is the core of `combine` and contains the submodules //! implementing all combine parsers. use crate::{ error::{ ErrorInfo, ParseError, ParseResult::{self, *}, ResultExt, StreamError, Token, Tracked, }, parser::{ combinator::{ and_then, flat_map, map, map_input, spanned, AndThen, Either, FlatMap, Map, MapInput, Spanned, }, error::{expected, message, silent, Expected, Message, Silent}, repeat::Iter, sequence::{then, then_partial, then_ref, Then, ThenPartial, ThenRef}, }, stream::{Stream, StreamErrorFor, StreamOnce}, ErrorOffset, }; use self::{ choice::{or, Or}, sequence::{skip, with, Skip, With}, }; #[cfg(feature = "alloc")] use alloc::boxed::Box; /// Internal API. May break without a semver bump #[macro_export] #[doc(hidden)] macro_rules! parse_mode { ($input_type: ty) => { #[inline] fn parse_partial( &mut self, input: &mut $input_type, state: &mut Self::PartialState, ) -> $crate::error::ParseResult::Error> { self.parse_mode($crate::parser::PartialMode::default(), input, state) } #[inline] fn parse_first( &mut self, input: &mut $input_type, state: &mut Self::PartialState, ) -> $crate::error::ParseResult::Error> { self.parse_mode($crate::parser::FirstMode, input, state) } }; } pub mod byte; pub mod char; pub mod choice; pub mod combinator; pub mod error; pub mod function; pub mod range; #[cfg(feature = "regex")] #[cfg_attr(docsrs, doc(cfg(feature = "regex")))] pub mod regex; pub mod repeat; pub mod sequence; pub mod token; /// By implementing the `Parser` trait a type says that it can be used to parse an input stream /// into the type `Output`. /// /// All methods have a default implementation but there needs to be at least an implementation of /// [`parse_stream`], [`parse_stream`], or [`parse_lazy`]. If the last is implemented, an /// implementation of [`add_error`] may also be required. See the documentation for /// [`parse_lazy`] for details. /// /// [`parse_stream`]: trait.Parser.html#method.parse_stream /// [`parse_stream`]: trait.Parser.html#method.parse_stream /// [`parse_lazy`]: trait.Parser.html#method.parse_lazy /// [`add_error`]: trait.Parser.html#method.add_error pub trait Parser { /// The type which is returned if the parser is successful. type Output; /// Determines the state necessary to resume parsing after more input is supplied. /// /// If partial parsing is not supported this can be set to `()`. type PartialState: Default; /// Entry point of the parser. Takes some input and tries to parse it. /// /// Returns the parsed result and the remaining input if the parser succeeds, or a /// error otherwise. /// /// This is the most straightforward entry point to a parser. Since it does not decorate the /// input in any way you may find the error messages a hard to read. If that is the case you /// may want to try wrapping your input with an [`easy::Stream`] or call [`easy_parse`] /// instead. /// /// [`easy::Stream`]: super::easy::Stream /// [`easy_parse`]: super::parser::EasyParser::easy_parse fn parse( &mut self, mut input: Input, ) -> Result<(Self::Output, Input), ::Error> { match self.parse_stream(&mut input).into() { Ok((v, _)) => Ok((v, input)), Err(error) => Err(error.into_inner().error), } } /// Entry point of the parser when using partial parsing. /// Takes some input and tries to parse it. /// /// Returns the parsed result and the remaining input if the parser succeeds, or a /// error otherwise. fn parse_with_state( &mut self, input: &mut Input, state: &mut Self::PartialState, ) -> Result::Error> { match self.parse_stream_partial(input, state).into() { Ok((v, _)) => Ok(v), Err(error) => Err(error.into_inner().error), } } /// Parses using the stream `input` by calling [`Stream::uncons`] one or more times. /// /// Semantically equivalent to [`parse_stream`], except this method returns a flattened result /// type, combining `Result` and [`Commit`] into a single [`ParseResult`]. /// /// [`Stream::uncons`]: super::stream::StreamOnce::uncons /// [`parse_stream`]: Parser::parse_stream /// [`Commit`]: super::error::Commit /// [`ParseResult`]: super::error::ParseResult #[inline] fn parse_stream( &mut self, input: &mut Input, ) -> ParseResult::Error> { let before = input.checkpoint(); let mut state = Default::default(); let mut result = self.parse_first(input, &mut state); if let ParseResult::PeekErr(ref mut error) = result { ctry!(input.reset(before.clone()).committed()); if let Ok(t) = input.uncons() { ctry!(input.reset(before).committed()); error.error.add_unexpected(Token(t)); } else { error.error.add(StreamErrorFor::::end_of_input()); } self.add_error(error); } result } /// Parses using the stream `input` by calling [`Stream::uncons`] one or more times. /// /// Specialized version of [`parse_stream`] which permits error value creation to be /// skipped in the common case. /// /// When this parser returns `PeekErr`, this method is allowed to return an empty /// [`Error`]. The error value that would have been returned can instead be obtained by /// calling [`add_error`]. This allows a parent parser such as `choice` to skip the creation of /// an unnecessary error value, if an alternative parser succeeds. /// /// Parsers should seek to implement this function instead of the above two if errors can be /// encountered before consuming input. The default implementation always returns all errors, /// with [`add_error`] being a no-op. /// /// [`Stream::uncons`]: super::stream::StreamOnce::uncons /// [`parse_stream`]: Parser::parse_stream /// [`Error`]: super::stream::StreamOnce::Error /// [`add_error`]: trait.Parser.html#method.add_error #[inline] fn parse_lazy( &mut self, input: &mut Input, ) -> ParseResult::Error> { if input.is_partial() { // If a partial parser were called from a non-partial parser (as it is here) we must // reset the input to before the partial parser were called on errors that committed // data as that parser's partial state was just temporary and it will not be able to // resume itself let before = input.checkpoint(); let result = self.parse_first(input, &mut Default::default()); if let CommitErr(_) = result { ctry!(input.reset(before).committed()); } result } else { self.parse_first(input, &mut Default::default()) } } /// Adds the first error that would normally be returned by this parser if it failed with an /// `PeekErr` result. /// /// See [`parse_lazy`] for details. /// /// [`parse_lazy`]: trait.Parser.html#method.parse_lazy fn add_error(&mut self, _error: &mut Tracked<::Error>) {} /// Like `parse_stream` but supports partial parsing. #[inline] fn parse_stream_partial( &mut self, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult::Error> { let before = input.checkpoint(); let mut result = self.parse_partial(input, state); if let ParseResult::PeekErr(ref mut error) = result { ctry!(input.reset(before.clone()).committed()); if let Ok(t) = input.uncons() { ctry!(input.reset(before).committed()); error.error.add_unexpected(Token(t)); } else { error.error.add(StreamErrorFor::::end_of_input()); } self.add_error(error); } result } /// Parses using the stream `input` and allows itself to be resumed at a later point using /// `parse_partial` by storing the necessary intermediate state in `state`. /// /// Unlike `parse_partial` function this is allowed to assume that there is no partial state to /// resume. /// /// Internal API. May break without a semver bump /// Always overridden by the `parse_mode!` macro #[inline] #[doc(hidden)] fn parse_first( &mut self, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult::Error> { self.parse_partial(input, state) } /// Parses using the stream `input` and allows itself to be resumed at a later point using /// `parse_partial` by storing the necessary intermediate state in `state` /// /// Internal API. May break without a semver bump /// Always overridden by the `parse_mode!` macro #[inline] #[doc(hidden)] fn parse_partial( &mut self, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult::Error> { let _ = state; self.parse_lazy(input) } /// Internal API. May break without a semver bump #[doc(hidden)] #[inline] fn parse_mode( &mut self, mode: M, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult::Error> where M: ParseMode, Self: Sized, { mode.parse(self, input, state) } /// Internal API. May break without a semver bump #[doc(hidden)] #[inline] fn parse_mode_impl( &mut self, mode: M, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult::Error> where M: ParseMode, Self: Sized, { if mode.is_first() { self.parse_first(input, state) } else { self.parse_partial(input, state) } } /// Internal API. May break without a semver bump #[doc(hidden)] #[inline] fn parse_committed_mode( &mut self, mode: M, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult::Error> where M: ParseMode, Self: Sized, { if mode.is_first() { FirstMode.parse_committed(self, input, state) } else { PartialMode::default().parse_committed(self, input, state) } } /// Returns how many parsers this parser contains /// /// Internal API: This should not be implemented explicitly outside of combine. #[doc(hidden)] fn parser_count(&self) -> ErrorOffset { ErrorOffset(1) } /// Internal API: This should not be implemented explicitly outside of combine. #[doc(hidden)] fn add_committed_expected_error(&mut self, _error: &mut Tracked<::Error>) { } /// Borrows a parser instead of consuming it. /// /// Used to apply parser combinators on `self` without losing ownership. /// /// ``` /// # extern crate combine; /// # use combine::*; /// # use combine::error::Commit; /// # use combine::parser::char::{digit, letter}; /// fn test(input: &mut &'static str) -> StdParseResult<(char, char), &'static str> { /// let mut p = digit(); /// let ((d, _), committed) = (p.by_ref(), letter()).parse_stream(input).into_result()?; /// let (d2, committed) = committed.combine(|_| p.parse_stream(input).into_result())?; /// Ok(((d, d2), committed)) /// } /// /// fn main() { /// let mut input = "1a23"; /// assert_eq!( /// test(&mut input).map(|(t, c)| (t, c.map(|_| input))), /// Ok((('1', '2'), Commit::Commit("3"))) /// ); /// } /// ``` fn by_ref(&mut self) -> &mut Self where Self: Sized, { self } /// Discards the value of the `self` parser and returns the value of `p`. /// Fails if any of the parsers fails. /// /// ``` /// # extern crate combine; /// # use combine::*; /// # use combine::parser::char::digit; /// # fn main() { /// let result = digit() /// .with(token('i')) /// .parse("9i") /// .map(|x| x.0); /// assert_eq!(result, Ok('i')); /// # } /// ``` fn with(self, p: P2) -> With where Self: Sized, P2: Parser, { with(self, p) } /// Discards the value of the `p` parser and returns the value of `self`. /// Fails if any of the parsers fails. /// /// ``` /// # extern crate combine; /// # use combine::*; /// # use combine::parser::char::digit; /// # fn main() { /// let result = digit() /// .skip(token('i')) /// .parse("9i") /// .map(|x| x.0); /// assert_eq!(result, Ok('9')); /// # } /// ``` fn skip(self, p: P2) -> Skip where Self: Sized, P2: Parser, { skip(self, p) } /// Parses with `self` followed by `p`. /// Succeeds if both parsers succeed, otherwise fails. /// Returns a tuple with both values on success. /// /// ``` /// # extern crate combine; /// # use combine::*; /// # use combine::parser::char::digit; /// # fn main() { /// let result = digit() /// .and(token('i')) /// .parse("9i") /// .map(|x| x.0); /// assert_eq!(result, Ok(('9', 'i'))); /// # } /// ``` fn and(self, p: P2) -> (Self, P2) where Self: Sized, P2: Parser, { (self, p) } /// Returns a parser which attempts to parse using `self`. If `self` fails without committing /// it tries to consume the same input using `p`. /// /// If you are looking to chain 3 or more parsers using `or` you may consider using the /// [`choice!`] macro instead, which can be clearer and may result in a faster parser. /// /// ``` /// # extern crate combine; /// # use combine::*; /// # use combine::parser::char::{digit, string}; /// # fn main() { /// let mut parser = string("let") /// .or(digit().map(|_| "digit")) /// .or(string("led")); /// assert_eq!(parser.parse("let"), Ok(("let", ""))); /// assert_eq!(parser.parse("1"), Ok(("digit", ""))); /// assert!(parser.parse("led").is_err()); /// /// let mut parser2 = string("two").or(string("three")); /// // Fails as the parser for "two" consumes the first 't' before failing /// assert!(parser2.parse("three").is_err()); /// /// // Use 'attempt' to make failing parsers always act as if they have not committed any input /// let mut parser3 = attempt(string("two")).or(attempt(string("three"))); /// assert_eq!(parser3.parse("three"), Ok(("three", ""))); /// # } /// ``` /// /// [`choice!`]: super::choice! fn or(self, p: P2) -> Or where Self: Sized, P2: Parser, { or(self, p) } /// Parses using `self` and then passes the value to `f` which returns a parser used to parse /// the rest of the input. /// /// Since the parser returned from `f` must have a single type it can be useful to use the /// [`left`](Parser::left) and [`right`](Parser::right) methods to merge parsers of differing types into one. /// /// If you are using partial parsing you may want to use [`then_partial`](Parser::then_partial) instead. /// /// ``` /// # #![cfg(feature = "std")] /// # extern crate combine; /// # use combine::*; /// # use combine::parser::char::digit; /// # use combine::error::Commit; /// # use combine::stream::easy; /// # fn main() { /// let result = digit() /// .then(|d| { /// if d == '9' { /// value(9).left() /// } /// else { /// unexpected_any(d).message("Not a nine").right() /// } /// }) /// .easy_parse("9"); /// assert_eq!(result, Ok((9, ""))); /// # } /// ``` fn then(self, f: F) -> Then where Self: Sized, F: FnMut(Self::Output) -> N, N: Parser, { then(self, f) } /// Variant of [`then`](Parser::then) which parses using `self` and then passes the value to `f` as a `&mut` reference. /// /// Useful when doing partial parsing since it does not need to store the parser returned by /// `f` in the partial state. Instead it will call `f` each to request a new parser each time /// parsing resumes and that parser is needed. /// /// Since the parser returned from `f` must have a single type it can be useful to use the /// [`left`](Parser::left) and [`right`](Parser::right) methods to merge parsers of differing types into one. /// /// ``` /// # #![cfg(feature = "std")] /// # extern crate combine; /// # use combine::*; /// # use combine::parser::char::digit; /// # use combine::error::Commit; /// # use combine::stream::easy; /// # fn main() { /// let result = digit() /// .then_partial(|d| { /// if *d == '9' { /// value(9).left() /// } /// else { /// unexpected_any(*d).message("Not a nine").right() /// } /// }) /// .easy_parse("9"); /// assert_eq!(result, Ok((9, ""))); /// # } /// ``` fn then_partial(self, f: F) -> ThenPartial where Self: Sized, F: FnMut(&mut Self::Output) -> N, N: Parser, { then_partial(self, f) } /// Parses using `self` and then passes a reference to the value to `f` which returns a parser /// used to parse the rest of the input. The value is then combined with the output of `f`. /// /// Since the parser returned from `f` must have a single type it can be useful to use the /// `left` and `right` methods to merge parsers of differing types into one. /// /// ``` /// # #![cfg(feature = "std")] /// # extern crate combine; /// # use combine::*; /// # use combine::parser::char::digit; /// # use combine::error::Commit; /// # use combine::stream::easy; /// # fn main() { /// let result = digit() /// .then_ref(|d| { /// if *d == '9' { /// digit().left() /// } /// else { /// unexpected_any(*d).message("Not a nine").right() /// } /// }) /// .easy_parse("98"); /// assert_eq!(result, Ok((('9', '8'), ""))); /// # } /// ``` fn then_ref(self, f: F) -> ThenRef where Self: Sized, F: FnMut(&Self::Output) -> N, N: Parser, { then_ref(self, f) } /// Uses `f` to map over the parsed value. /// /// ``` /// # extern crate combine; /// # use combine::*; /// # use combine::parser::char::digit; /// # fn main() { /// let result = digit() /// .map(|c| c == '9') /// .parse("9") /// .map(|x| x.0); /// assert_eq!(result, Ok(true)); /// # } /// ``` fn map(self, f: F) -> Map where Self: Sized, F: FnMut(Self::Output) -> B, { map(self, f) } fn map_input(self, f: F) -> MapInput where Self: Sized, F: FnMut(Self::Output, &mut Input) -> B, { map_input(self, f) } /// Uses `f` to map over the output of `self`. If `f` returns an error the parser fails. /// /// ``` /// # extern crate combine; /// # use combine::*; /// # use combine::parser::char::digit; /// # use combine::parser::range::take; /// # fn main() { /// let result = take(4) /// .flat_map(|bs| many(digit()).parse(bs).map(|t| t.0)) /// .parse("12abcd"); /// assert_eq!(result, Ok((String::from("12"), "cd"))); /// # } /// ``` fn flat_map(self, f: F) -> FlatMap where Self: Sized, F: FnMut(Self::Output) -> Result::Error>, { flat_map(self, f) } /// Parses with `self` and if it fails, adds the message `msg` to the error. /// /// ``` /// # #![cfg(feature = "std")] /// # extern crate combine; /// # use combine::*; /// # use combine::stream::easy; /// # use combine::stream::position::{self, SourcePosition}; /// # fn main() { /// let result = token('9') /// .message("Not a nine") /// .easy_parse(position::Stream::new("8")); /// assert_eq!(result, Err(easy::Errors { /// position: SourcePosition::default(), /// errors: vec![ /// easy::Error::Unexpected('8'.into()), /// easy::Error::Expected('9'.into()), /// easy::Error::Message("Not a nine".into()) /// ] /// })); /// # } /// ``` fn message(self, msg: S) -> Message where Self: Sized, S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>, { message(self, msg) } /// Parses with `self` and if it fails without consuming any input any expected errors are /// replaced by `msg`. `msg` is then used in error messages as "Expected `msg`". /// /// ``` /// # #![cfg(feature = "std")] /// # extern crate combine; /// # use combine::*; /// # use combine::error; /// # use combine::stream::easy; /// # use combine::stream::position::{self, SourcePosition}; /// # fn main() { /// let result = token('9') /// .expected("nine") /// .easy_parse(position::Stream::new("8")); /// assert_eq!(result, Err(easy::Errors { /// position: SourcePosition::default(), /// errors: vec![ /// easy::Error::Unexpected('8'.into()), /// easy::Error::Expected("nine".into()) /// ] /// })); /// /// let result = token('9') /// .expected(error::Format(format_args!("That is not a nine!"))) /// .easy_parse(position::Stream::new("8")); /// assert_eq!(result, Err(easy::Errors { /// position: SourcePosition::default(), /// errors: vec![ /// easy::Error::Unexpected('8'.into()), /// easy::Error::Expected("That is not a nine!".to_string().into()) /// ] /// })); /// # } /// ``` fn expected(self, msg: S) -> Expected where Self: Sized, S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>, { expected(self, msg) } /// Parses with `self`, if it fails without consuming any input any expected errors that would /// otherwise be emitted by `self` are suppressed. /// /// ``` /// # #![cfg(feature = "std")] /// # extern crate combine; /// # use combine::*; /// # use combine::stream::easy; /// # use combine::stream::position::{self, SourcePosition}; /// # fn main() { /// let result = token('9') /// .expected("nine") /// .silent() /// .easy_parse(position::Stream::new("8")); /// assert_eq!(result, Err(easy::Errors { /// position: SourcePosition::default(), /// errors: vec![ /// easy::Error::Unexpected('8'.into()), /// ] /// })); /// # } /// ``` fn silent(self) -> Silent where Self: Sized, { silent(self) } /// Parses with `self` and applies `f` on the result if `self` parses successfully. /// `f` may optionally fail with an error which is automatically converted to a `ParseError`. /// /// ``` /// # extern crate combine; /// # use combine::*; /// # use combine::stream::position::{self, SourcePosition}; /// # use combine::parser::char::digit; /// # fn main() { /// let mut parser = many1(digit()) /// .and_then(|s: String| s.parse::()); /// let result = parser.easy_parse(position::Stream::new("1234")).map(|(x, state)| (x, state.input)); /// assert_eq!(result, Ok((1234, ""))); /// let result = parser.easy_parse(position::Stream::new("999999999999999999999999")); /// assert!(result.is_err()); /// // Errors are report as if they occurred at the start of the parse /// assert_eq!(result.unwrap_err().position, SourcePosition { line: 1, column: 1 }); /// # } /// ``` fn and_then(self, f: F) -> AndThen where Self: Parser + Sized, F: FnMut(Self::Output) -> Result, E: Into< >::StreamError, >, { and_then(self, f) } /// Creates an iterator from a parser and a state. Can be used as an alternative to [`many`] /// when collecting directly into a `Extend` type is not desirable. /// /// ``` /// # extern crate combine; /// # use combine::*; /// # use combine::parser::char::{char, digit}; /// # fn main() { /// let mut buffer = String::new(); /// let number = parser(|input| { /// buffer.clear(); /// let mut iter = digit().iter(input); /// buffer.extend(&mut iter); /// let i = buffer.parse::().unwrap(); /// iter.into_result(i) /// }); /// let result = sep_by(number, char(',')) /// .parse("123,45,6"); /// assert_eq!(result, Ok((vec![123, 45, 6], ""))); /// # } /// ``` /// /// [`many`]: repeat::many fn iter(self, input: &mut Input) -> Iter<'_, Input, Self, Self::PartialState, FirstMode> where Self: Parser + Sized, { Iter::new(self, FirstMode, input, Default::default()) } /// Creates an iterator from a parser and a state. Can be used as an alternative to [`many`] /// when collecting directly into a `Extend` type is not desirable. /// /// ``` /// # extern crate combine; /// # use combine::*; /// # use combine::parser::char::{char, digit}; /// # fn main() { /// let mut buffer = String::new(); /// let number = parser(|input| { /// buffer.clear(); /// let mut iter = digit().iter(input); /// buffer.extend(&mut iter); /// let i = buffer.parse::().unwrap(); /// iter.into_result(i) /// }); /// let result = sep_by(number, char(',')) /// .parse("123,45,6"); /// assert_eq!(result, Ok((vec![123, 45, 6], ""))); /// # } /// ``` /// /// [`many`]: repeat::many fn partial_iter<'a, 's, M>( self, mode: M, input: &'a mut Input, partial_state: &'s mut Self::PartialState, ) -> Iter<'a, Input, Self, &'s mut Self::PartialState, M> where Self: Parser + Sized, M: ParseMode, { Iter::new(self, mode, input, partial_state) } /// Turns the parser into a trait object by putting it in a `Box`. Can be used to easily /// return parsers from functions without naming the type. /// /// ``` /// # use combine::*; /// # fn main() { /// fn test<'input, F>( /// c: char, /// f: F) /// -> Box + 'input> /// where F: FnMut(char) -> bool + 'static /// { /// combine::parser::combinator::no_partial((token(c), satisfy(f))).boxed() /// } /// let result = test('a', |c| c >= 'a' && c <= 'f') /// .parse("ac"); /// assert_eq!(result, Ok((('a', 'c'), ""))); /// # } /// ``` #[cfg(feature = "alloc")] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] fn boxed<'a>( self, ) -> Box + 'a> where Self: Sized + 'a, { Box::new(self) } /// Wraps the parser into the [`Either`](combinator::Either) enum which allows combinators such as [`then`](Parser::then) to return /// multiple different parser types (merging them to one) /// /// ``` /// # extern crate combine; /// # use combine::*; /// # use combine::parser::char::{digit, letter}; /// # fn main() { /// let mut parser = any().then(|c| /// if c == '#' { /// skip_many(satisfy(|c| c != '\n')) /// .with(value("".to_string())) /// .left() /// } else { /// many1(letter()) /// .map(move |mut s: String| { s.insert(0, c); s }) /// .right() /// }); /// /// let result = parser.parse("ac2"); /// assert_eq!(result, Ok(("ac".to_string(), "2"))); /// /// let result = parser.parse("# ac2"); /// assert_eq!(result, Ok(("".to_string(), ""))); /// # } /// ``` fn left(self) -> Either where Self: Sized, R: Parser, { Either::Left(self) } /// Wraps the parser into the [`Either`](combinator::Either) enum which allows combinators such as [`then`](Parser::then) to return /// multiple different parser types (merging them to one) /// /// ``` /// # extern crate combine; /// # use combine::*; /// # use combine::parser::char::{digit, letter}; /// # fn main() { /// let mut parser = any().then(|c| /// if c == '#' { /// skip_many(satisfy(|c| c != '\n')) /// .with(value("".to_string())) /// .left() /// } else { /// many1(letter()) /// .map(move |mut s: String| { s.insert(0, c); s }) /// .right() /// }); /// /// let result = parser.parse("ac2"); /// assert_eq!(result, Ok(("ac".to_string(), "2"))); /// /// let result = parser.parse("# ac2"); /// assert_eq!(result, Ok(("".to_string(), ""))); /// # } /// ``` fn right(self) -> Either where Self: Sized, L: Parser, { Either::Right(self) } /// Marks errors produced inside the `self` parser with the span from the start of the parse to /// the end of it. /// /// [`p.spanned()`]: ../trait.Parser.html#method.spanned /// /// ``` /// use combine::{*, parser::{char::string, combinator::spanned}}; /// use combine::stream::{easy, span}; /// /// let input = "hel"; /// let result = spanned(string("hello")).parse( /// span::Stream::<_, easy::Errors<_, _, span::Span<_>>>::from(easy::Stream::from(input)), /// ); /// assert!(result.is_err()); /// assert_eq!( /// result.unwrap_err().position.map(|p| p.translate_position(input)), /// span::Span { start: 0, end: 3 }, /// ); /// ``` fn spanned(self) -> Spanned where Self: Sized, { spanned(self) } } /// Provides the `easy_parse` method which provides good error messages by default #[cfg(feature = "std")] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] pub trait EasyParser: Parser> where Input::Token: PartialEq, Input::Range: PartialEq, { /// Entry point of the parser. Takes some input and tries to parse it, returning an easy to use /// and format error if parsing did not succeed. /// /// Returns the parsed result and the remaining input if the parser succeeds, or a /// This function wraps requires `Input == easy::Stream` which makes it return /// return `easy::Errors` if an error occurs. Due to this wrapping it is recommended that the /// parser `Self` is written with a generic input type. /// /// ``` /// # #[macro_use] /// # extern crate combine; /// /// use combine::*; /// use combine::parser::repeat::many1; /// use combine::parser::char::letter; /// /// // Good! /// parser!{ /// fn my_parser[Input]()(Input) -> String /// where [Input: Stream] /// { /// many1::(letter()) /// } /// } /// /// // Won't compile with `easy_parse` since it is specialized on `&str` /// parser!{ /// fn my_parser2['a]()(&'a str) -> String /// where [&'a str: Stream] /// { /// many1(letter()) /// } /// } /// /// fn main() { /// assert_eq!(my_parser().parse("abc"), Ok(("abc".to_string(), ""))); /// // Would fail to compile if uncommented /// // my_parser2().parse("abc") /// } /// ``` /// /// [`ParseError`]: struct.ParseError.html fn easy_parse( &mut self, input: Input, ) -> Result< (>>::Output, Input), crate::easy::ParseError, > where Input: Stream, crate::easy::Stream: StreamOnce< Token = Input::Token, Range = Input::Range, Error = crate::easy::ParseError>, Position = Input::Position, >, Input::Position: Default, Self: Sized + Parser>, { let input = crate::easy::Stream(input); self.parse(input).map(|(v, input)| (v, input.0)) } } #[cfg(feature = "std")] impl EasyParser for P where P: ?Sized + Parser>, Input: Stream, Input::Token: PartialEq, Input::Range: PartialEq, { } macro_rules! forward_deref { (Input) => { type Output = P::Output; type PartialState = P::PartialState; #[inline] fn parse_first( &mut self, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult::Error> { (**self).parse_first(input, state) } #[inline] fn parse_partial( &mut self, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult::Error> { (**self).parse_partial(input, state) } #[inline] fn add_error(&mut self, error: &mut Tracked<::Error>) { (**self).add_error(error) } #[inline] fn add_committed_expected_error( &mut self, error: &mut Tracked<::Error>, ) { (**self).add_committed_expected_error(error) } #[inline] fn parser_count(&self) -> ErrorOffset { (**self).parser_count() } }; } impl<'a, P, Input> Parser for &'a mut P where P: ?Sized + Parser, Input: Stream, { forward_deref!(Input); } #[cfg(feature = "alloc")] impl Parser for Box

where P: ?Sized + Parser, Input: Stream, { forward_deref!(Input); } /// Internal API. May break without a semver bump #[doc(hidden)] /// Specifies whether the parser must check for partial state that must be resumed pub trait ParseMode: Copy { /// If `true` then the parser has no previous state to resume otherwise the parser *might* have /// state to resume which it must check. fn is_first(self) -> bool; /// Puts the mode into `first` parsing. fn set_first(&mut self); fn parse( self, parser: &mut P, input: &mut Input, state: &mut P::PartialState, ) -> ParseResult where P: Parser, Input: Stream; #[inline] fn parse_committed( self, parser: &mut P, input: &mut Input, state: &mut P::PartialState, ) -> ParseResult::Error> where P: Parser, Input: Stream, { let before = input.checkpoint(); let mut result = parser.parse_mode_impl(self, input, state); if let ParseResult::PeekErr(ref mut error) = result { ctry!(input.reset(before.clone()).committed()); if let Ok(t) = input.uncons() { ctry!(input.reset(before).committed()); error.error.add_unexpected(Token(t)); } else { error.error.add(StreamErrorFor::::end_of_input()); } parser.add_error(error); } result } } /// Internal API. May break without a semver bump #[doc(hidden)] #[derive(Copy, Clone)] pub struct FirstMode; impl ParseMode for FirstMode { #[inline] fn is_first(self) -> bool { true } #[inline] fn set_first(&mut self) {} fn parse( self, parser: &mut P, input: &mut Input, state: &mut P::PartialState, ) -> ParseResult where P: Parser, Input: Stream, { parser.parse_mode_impl(FirstMode, input, state) } } /// Internal API. May break without a semver bump #[doc(hidden)] #[derive(Copy, Clone, Default)] pub struct PartialMode { pub first: bool, } impl ParseMode for PartialMode { #[inline] fn is_first(self) -> bool { self.first } #[inline] fn set_first(&mut self) { self.first = true; } fn parse( self, parser: &mut P, input: &mut Input, state: &mut P::PartialState, ) -> ParseResult where P: Parser, Input: Stream, { if self.is_first() { parser.parse_mode_impl(FirstMode, input, state) } else { parser.parse_mode_impl(self, input, state) } } }