| { | ||
| "git": { | ||
| "sha1": "4ab5ee9c74617b474bae7013f10daa8e73031add" | ||
| "sha1": "a5199c9ff48a45a773befbfb2296f3ecabfa6ed1" | ||
| } | ||
| } |
+0
-2
@@ -19,7 +19,5 @@ language: rust | ||
| - | | ||
| pip install 'travis-cargo<0.2' --user && | ||
| export PATH=$HOME/.local/bin:$PATH | ||
| script: | ||
| - ./travis.sh | ||
| - travis-cargo --only stable doc | ||
| after_success: | | ||
@@ -26,0 +24,0 @@ if [[ "$TRAVIS_RUST_VERSION" == stable ]]; then |
+1
-1
@@ -269,3 +269,3 @@ # This file is automatically @generated by Cargo. | ||
| name = "combine" | ||
| version = "4.5.2" | ||
| version = "4.6.0" | ||
| dependencies = [ | ||
@@ -272,0 +272,0 @@ "async-std", |
+1
-1
@@ -16,3 +16,3 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO | ||
| name = "combine" | ||
| version = "4.5.2" | ||
| version = "4.6.0" | ||
| authors = ["Markus Westerlind <marwes91@gmail.com>"] | ||
@@ -19,0 +19,0 @@ description = "Fast parser combinators on arbitrary streams with zero-copy support." |
+10
-0
@@ -0,1 +1,11 @@ | ||
| <a name="v4.6.0"></a> | ||
| ## v4.6.0 (2021-06-16) | ||
| #### Features | ||
| * Add decode_tokio ([aa20bf64](https://github.com/Marwes/combine/commit/aa20bf641bc5deed7e521de289f2b0963034f750)) | ||
| <a name="v4.5.2"></a> | ||
@@ -2,0 +12,0 @@ ### v4.5.2 (2021-01-07) |
+1
-1
@@ -887,3 +887,3 @@ //! This crate contains parser combinators, roughly based on the Haskell libraries | ||
| let result = p.easy_parse(position::Stream::new("[1][2][]")); | ||
| assert!(result.is_err(), format!("{:?}", result)); | ||
| assert!(result.is_err(), "{:?}", result); | ||
| let error = result.map(|x| format!("{:?}", x)).unwrap_err(); | ||
@@ -890,0 +890,0 @@ assert_eq!(error.position, SourcePosition { line: 1, column: 8 }); |
@@ -10,3 +10,3 @@ //! A collection of both concrete parsers as well as parser combinators. | ||
| ParseResult::{self, *}, | ||
| ResultExt, Token, Tracked, | ||
| ResultExt, StreamError, Token, Tracked, | ||
| }, | ||
@@ -22,3 +22,3 @@ parser::{ | ||
| }, | ||
| stream::{Stream, StreamOnce}, | ||
| stream::{Stream, StreamErrorFor, StreamOnce}, | ||
| ErrorOffset, | ||
@@ -152,2 +152,4 @@ }; | ||
| error.error.add_unexpected(Token(t)); | ||
| } else { | ||
| error.error.add(StreamErrorFor::<Input>::end_of_input()); | ||
| } | ||
@@ -220,2 +222,4 @@ self.add_error(error); | ||
| error.error.add_unexpected(Token(t)); | ||
| } else { | ||
| error.error.add(StreamErrorFor::<Input>::end_of_input()); | ||
| } | ||
@@ -1136,2 +1140,4 @@ self.add_error(error); | ||
| error.error.add_unexpected(Token(t)); | ||
| } else { | ||
| error.error.add(StreamErrorFor::<Input>::end_of_input()); | ||
| } | ||
@@ -1138,0 +1144,0 @@ parser.add_error(error); |
+15
-7
@@ -248,3 +248,3 @@ //! Combinators which take one or more parsers and applies them repeatedly. | ||
| Ok, | ||
| PeekErr, | ||
| PeekErr(E), | ||
| CommitErr(E), | ||
@@ -277,3 +277,3 @@ } | ||
| match self.state { | ||
| State::Ok | State::PeekErr => { | ||
| State::Ok | State::PeekErr(_) => { | ||
| if self.committed { | ||
@@ -294,3 +294,3 @@ CommitOk(value) | ||
| match self.state { | ||
| State::Ok | State::PeekErr => { | ||
| State::Ok | State::PeekErr(_) => { | ||
| let value = mem::take(value); | ||
@@ -316,3 +316,3 @@ if self.committed { | ||
| match self.state { | ||
| State::Ok | State::PeekErr => { | ||
| State::Ok => { | ||
| let err = <Input as StreamOnce>::Error::from_error(self.input.position(), err); | ||
@@ -325,2 +325,11 @@ if self.committed { | ||
| } | ||
| State::PeekErr(mut e) => { | ||
| let err = <Input as StreamOnce>::Error::from_error(self.input.position(), err); | ||
| e = e.merge(err); | ||
| if self.committed { | ||
| CommitErr(e) | ||
| } else { | ||
| PeekErr(e.into()) | ||
| } | ||
| } | ||
| State::CommitErr(mut e) => { | ||
@@ -358,8 +367,7 @@ e.add(err); | ||
| } | ||
| PeekErr(_) => { | ||
| PeekErr(e) => { | ||
| self.state = match self.input.reset(before) { | ||
| Err(err) => State::CommitErr(err), | ||
| Ok(_) => State::PeekErr, | ||
| Ok(_) => State::PeekErr(e.error), | ||
| }; | ||
| self.state = State::PeekErr; | ||
| None | ||
@@ -366,0 +374,0 @@ } |
@@ -75,2 +75,3 @@ //! Combinators which take multiple parsers and applies them one after another. | ||
| )* | ||
| #[allow(dead_code)] | ||
| offset: u8, | ||
@@ -77,0 +78,0 @@ _marker: PhantomData <( $h, $( $id),* )>, |
+74
-9
@@ -207,5 +207,7 @@ // | ||
| let mut committed = false; | ||
| let mut started_at_eoi = true; | ||
| let result = self.uncons_while(|c| { | ||
| let ok = f(c); | ||
| committed |= ok; | ||
| started_at_eoi = false; | ||
| ok | ||
@@ -218,2 +220,4 @@ }); | ||
| } | ||
| } else if started_at_eoi { | ||
| PeekErr(Tracked::from(StreamErrorFor::<Self>::end_of_input())) | ||
| } else { | ||
@@ -563,3 +567,3 @@ PeekErr(Tracked::from( | ||
| } | ||
| None => return PeekErr(Tracked::from(StringStreamError::UnexpectedParse)), | ||
| None => return PeekErr(Tracked::from(StringStreamError::Eoi)), | ||
| } | ||
@@ -689,4 +693,11 @@ | ||
| { | ||
| if !self.first().cloned().map_or(false, &mut f) { | ||
| return PeekErr(Tracked::from(UnexpectedParse::Unexpected)); | ||
| match self.first() { | ||
| Some(c) => { | ||
| if !f(c.clone()) { | ||
| return PeekErr(Tracked::from(UnexpectedParse::Unexpected)); | ||
| } | ||
| } | ||
| None => { | ||
| return PeekErr(Tracked::from(UnexpectedParse::Eoi)); | ||
| } | ||
| } | ||
@@ -1126,4 +1137,9 @@ | ||
| { | ||
| if !self.0.first().map_or(false, &mut f) { | ||
| return PeekErr(Tracked::from(UnexpectedParse::Unexpected)); | ||
| match self.0.first() { | ||
| Some(c) => { | ||
| if !f(c) { | ||
| return PeekErr(Tracked::from(UnexpectedParse::Unexpected)); | ||
| } | ||
| } | ||
| None => return PeekErr(Tracked::from(UnexpectedParse::Eoi)), | ||
| } | ||
@@ -1284,3 +1300,3 @@ | ||
| mut parser: P, | ||
| mut input: &mut Input, | ||
| input: &mut Input, | ||
| partial_state: &mut P::PartialState, | ||
@@ -1293,7 +1309,13 @@ ) -> Result<(Option<P::Output>, usize), <Input as StreamOnce>::Error> | ||
| let start = input.checkpoint(); | ||
| match parser.parse_with_state(&mut input, partial_state) { | ||
| match parser.parse_with_state(input, partial_state) { | ||
| Ok(message) => Ok((Some(message), input.distance(&start))), | ||
| Err(err) => { | ||
| if input.is_partial() && err.is_unexpected_end_of_input() { | ||
| Ok((None, input.distance(&start))) | ||
| if err.is_unexpected_end_of_input() { | ||
| if input.is_partial() { | ||
| // The parser expected more input to parse and input is partial, return `None` | ||
| // as we did not finish and also return how much may be removed from the stream | ||
| Ok((None, input.distance(&start))) | ||
| } else { | ||
| Err(err) | ||
| } | ||
| } else { | ||
@@ -1306,2 +1328,45 @@ Err(err) | ||
| /// Decodes `input` using `parser`. Like `decode` but works directly in both | ||
| /// `tokio_util::Decoder::decode` and `tokio_util::Decoder::decode_eof` | ||
| /// | ||
| /// Return `Ok(Some(token), committed_data)` if there was enough data to finish parsing using | ||
| /// `parser`. | ||
| /// Returns `Ok(None, committed_data)` if `input` did not contain enough data to finish parsing | ||
| /// using `parser`. | ||
| /// Returns `Ok(None, 0)` if `input` did not contain enough data to finish parsing | ||
| /// using `parser`. | ||
| /// | ||
| /// See `examples/async.rs` for example usage in a `tokio_io::codec::Decoder` | ||
| pub fn decode_tokio<Input, P>( | ||
| mut parser: P, | ||
| input: &mut Input, | ||
| partial_state: &mut P::PartialState, | ||
| ) -> Result<(Option<P::Output>, usize), <Input as StreamOnce>::Error> | ||
| where | ||
| P: Parser<Input>, | ||
| Input: RangeStream, | ||
| { | ||
| let start = input.checkpoint(); | ||
| match parser.parse_with_state(input, partial_state) { | ||
| Ok(message) => Ok((Some(message), input.distance(&start))), | ||
| Err(err) => { | ||
| if err.is_unexpected_end_of_input() { | ||
| if input.is_partial() { | ||
| // The parser expected more input to parse and input is partial, return `None` | ||
| // as we did not finish and also return how much may be removed from the stream | ||
| Ok((None, input.distance(&start))) | ||
| } else if input_at_eof(input) && input.distance(&start) == 0 { | ||
| // We are at eof and the input is empty, return None to indicate that we are | ||
| // done | ||
| Ok((None, 0)) | ||
| } else { | ||
| Err(err) | ||
| } | ||
| } else { | ||
| Err(err) | ||
| } | ||
| } | ||
| } | ||
| } | ||
| /// Parses an instance of `std::io::Read` as a `&[u8]` without reading the entire file into | ||
@@ -1308,0 +1373,0 @@ /// memory. |
+32
-15
@@ -96,2 +96,5 @@ #![allow(renamed_and_removed_lints)] | ||
| } | ||
| fn decode_eof(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> { | ||
| (&mut &mut *self).decode_eof(src) | ||
| } | ||
| } | ||
@@ -104,8 +107,17 @@ | ||
| fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> { | ||
| self.decode_stream(src, false) | ||
| } | ||
| fn decode_eof(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> { | ||
| self.decode_stream(src, true) | ||
| } | ||
| } | ||
| impl<'a> $typ { | ||
| fn decode_stream(&mut self, src: &mut BytesMut, eof: bool) -> Result<Option<$token>, Error> { | ||
| let (opt, removed_len) = { | ||
| let str_src = str::from_utf8(&src[..])?; | ||
| println!("Decoding `{}`", str_src); | ||
| combine::stream::decode( | ||
| combine::stream::decode_tokio( | ||
| any_partial_state(mk_parser!($parser, self, ($($custom_state)*))), | ||
| &mut easy::Stream(combine::stream::PartialStream(str_src)), | ||
| &mut easy::Stream(combine::stream::MaybePartialStream(str_src, !eof)), | ||
| &mut self.0, | ||
@@ -799,3 +811,3 @@ ).map_err(|err| { | ||
| #[tokio::main] | ||
| #[tokio::test] | ||
| async fn decode_loop() { | ||
@@ -814,4 +826,4 @@ use tokio::fs::File; | ||
| loop { | ||
| // Suppresses a warning about duplicate label | ||
| async { | ||
| // async block suppresses a warning about duplicate label | ||
| if async { | ||
| decode_tokio!( | ||
@@ -823,17 +835,22 @@ decoder, | ||
| ) | ||
| .unwrap(); | ||
| .is_err() | ||
| } | ||
| .await; | ||
| .await | ||
| { | ||
| break; | ||
| } | ||
| count += 1; | ||
| if decode_tokio!( | ||
| decoder, | ||
| read, | ||
| skip_many1(satisfy(is_whitespace)), | ||
| |input, _position| combine::easy::Stream::from(input), | ||
| ) | ||
| .is_err() | ||
| { | ||
| break; | ||
| if decode_tokio!( | ||
| decoder, | ||
| read, | ||
| skip_many1(satisfy(is_whitespace)), | ||
| |input, _position| combine::easy::Stream::from(input), | ||
| ) | ||
| .is_err() | ||
| { | ||
| break; | ||
| } | ||
| } | ||
@@ -840,0 +857,0 @@ } |
+4
-0
@@ -21,1 +21,5 @@ #!/bin/bash -x | ||
| fi | ||
| if [[ "$TRAVIS_RUST_VERSION" == "stable" ]]; then | ||
| cargo doc | ||
| fi |
Sorry, the diff of this file is not supported yet