• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![allow(renamed_and_removed_lints)]
2 
3 use std::{
4     cell::Cell,
5     io::{self, Cursor},
6     rc::Rc,
7     str,
8 };
9 
10 use {
11     bytes::{Buf, BytesMut},
12     combine::{
13         any, count_min_max,
14         error::{ParseError, StreamError},
15         many1, parser,
16         parser::{
17             byte::{num, take_until_bytes},
18             char::{char, digit, letter, string},
19             choice::optional,
20             combinator::{
21                 any_partial_state, any_send_partial_state, attempt, from_str, no_partial,
22                 recognize, AnyPartialState, AnySendPartialState,
23             },
24             range::{
25                 self, range, recognize_with_value, take, take_fn, take_until_range, take_while,
26                 take_while1,
27             },
28             repeat,
29         },
30         satisfy, sep_end_by, skip_many, skip_many1,
31         stream::{easy, RangeStream, StreamErrorFor},
32         token, Parser,
33     },
34     futures::prelude::*,
35     futures_03_dep as futures,
36     partial_io::PartialRead,
37     quick_error::quick_error,
38     quickcheck::quickcheck,
39     tokio_dep as tokio,
40     tokio_util::codec::{Decoder, FramedRead},
41 };
42 
43 // Workaround partial_io not working with tokio-0.2
44 mod support;
45 use support::*;
46 
47 quick_error! {
48     #[derive(Debug)]
49     enum Error {
50         Io(err: io::Error) {
51             display("{}", err)
52             from()
53         }
54         Parse(err: easy::Errors<char, String, usize>) {
55             display("{}", err)
56             from()
57         }
58         Utf8(err: std::str::Utf8Error) {
59             display("{}", err)
60             from()
61         }
62         Message(err: String) {
63             display("{}", err)
64             from()
65         }
66     }
67 }
68 
69 macro_rules! mk_parser {
70     ($parser:expr, $self_:expr,()) => {
71         $parser
72     };
73     ($parser:expr, $self_:expr,($custom_state:ty)) => {
74         $parser($self_.1.clone())
75     };
76 }
77 macro_rules! impl_decoder {
78     ($typ: ident, $token: ty, $parser: expr, $custom_state: ty) => {
79         #[derive(Default)]
80         struct $typ(AnyPartialState, $custom_state);
81         impl_decoder!{$typ, $token, $parser; ($custom_state)}
82     };
83     ($typ: ident, $token: ty, $parser: expr) => {
84         #[derive(Default)]
85         struct $typ(AnyPartialState);
86         impl_decoder!{$typ, $token, $parser; ()}
87     };
88     ($typ: ident, $token: ty, $parser: expr; ( $($custom_state: tt)* )) => {
89         impl Decoder for $typ {
90             type Item = $token;
91             type Error = Error;
92 
93             fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
94                 (&mut &mut *self).decode(src)
95             }
96             fn decode_eof(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
97                 (&mut &mut *self).decode_eof(src)
98             }
99         }
100 
101         impl<'a> Decoder for &'a mut $typ {
102             type Item = $token;
103             type Error = Error;
104 
105             fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
106                 self.decode_stream(src, false)
107             }
108             fn decode_eof(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
109                 self.decode_stream(src, true)
110             }
111         }
112 
113         impl<'a> $typ {
114             fn decode_stream(&mut self, src: &mut BytesMut, eof: bool) -> Result<Option<$token>, Error> {
115                 let (opt, removed_len) = {
116                     let str_src = str::from_utf8(&src[..])?;
117                     println!("Decoding `{}`", str_src);
118                     combine::stream::decode_tokio(
119                         any_partial_state(mk_parser!($parser, self, ($($custom_state)*))),
120                         &mut easy::Stream(combine::stream::MaybePartialStream(str_src, !eof)),
121                         &mut self.0,
122                     ).map_err(|err| {
123                         // Since err contains references into `src` we must remove these before
124                         // returning the error and before we call `advance` to remove the input we
125                         // just committed
126                         let err = err.map_range(|r| r.to_string())
127                             .map_position(|p| p.translate_position(&str_src[..]));
128                         format!("{}\nIn input: `{}`", err, str_src)
129                     })?
130                 };
131 
132                 src.advance(removed_len);
133                 match opt {
134                     None => println!("Need more input!"),
135                     Some(_) => (),
136                 }
137                 Ok(opt)
138             }
139         }
140     }
141 }
142 
143 macro_rules! impl_byte_decoder {
144     ($typ: ident, $token: ty, $parser: expr, $custom_state: ty) => {
145         #[derive(Default)]
146         struct $typ(AnyPartialState, $custom_state);
147         impl_byte_decoder!{$typ, $token, $parser; ($custom_state)}
148     };
149     ($typ: ident, $token: ty, $parser: expr) => {
150         #[derive(Default)]
151         struct $typ(AnyPartialState);
152         impl_byte_decoder!{$typ, $token, $parser; ()}
153     };
154     ($typ: ident, $token: ty, $parser: expr; ( $($custom_state: tt)* )) => {
155         impl Decoder for $typ {
156             type Item = $token;
157             type Error = Error;
158 
159             fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
160                 (&mut &mut *self).decode(src)
161             }
162         }
163 
164         impl<'a> Decoder for &'a mut $typ {
165             type Item = $token;
166             type Error = Error;
167 
168             fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
169                 let (opt, removed_len) = {
170                     let str_src = &src[..];
171                     println!("Decoding `{:?}`", str_src);
172                     combine::stream::decode(
173                         any_partial_state(mk_parser!($parser, self, ($($custom_state)*))),
174                         &mut easy::Stream(combine::stream::PartialStream(str_src)),
175                         &mut self.0,
176                     ).map_err(|err| {
177                         // Since err contains references into `src` we must remove these before
178                         // returning the error and before we call `advance` to remove the input we
179                         // just committed
180                         let err = err.map_range(|r| format!("{:?}", r))
181                             .map_position(|p| p.translate_position(&str_src[..]));
182                         format!("{}\nIn input: `{:?}`", err, str_src)
183                     })?
184                 };
185 
186                 src.advance(removed_len);
187                 match opt {
188                     None => println!("Need more input!"),
189                     Some(_) => (),
190                 }
191                 Ok(opt)
192             }
193         }
194     }
195 }
196 
197 use partial_io::{GenNoErrors, GenWouldBlock, PartialOp, PartialWithErrors};
198 
run_decoder<B, D, S>(input: &B, seq: S, decoder: D) -> Result<Vec<D::Item>, D::Error> where D: Decoder<Error = Error>, D::Item: ::std::fmt::Debug, S: IntoIterator<Item = PartialOp> + 'static, S::IntoIter: Send, B: ?Sized + AsRef<[u8]>,199 fn run_decoder<B, D, S>(input: &B, seq: S, decoder: D) -> Result<Vec<D::Item>, D::Error>
200 where
201     D: Decoder<Error = Error>,
202     D::Item: ::std::fmt::Debug,
203     S: IntoIterator<Item = PartialOp> + 'static,
204     S::IntoIter: Send,
205     B: ?Sized + AsRef<[u8]>,
206 {
207     let ref mut reader = Cursor::new(input.as_ref());
208     let partial_reader = PartialAsyncRead::new(reader, seq);
209 
210     tokio_02_dep::runtime::Builder::new()
211         .basic_scheduler()
212         .build()
213         .unwrap()
214         .block_on(
215             FramedRead::new(partial_reader, decoder)
216                 .map_ok(|x| {
217                     println!("Decoded `{:?}`", x);
218                     x
219                 })
220                 .try_collect(),
221         )
222 }
223 
224 parser! {
225     type PartialState = AnyPartialState;
226     fn basic_parser['a, Input]()(Input) -> String
227         where [ Input: RangeStream<Token = char, Range = &'a str> ]
228     {
229         any_partial_state(
230             many1(digit()).skip(range(&"\r\n"[..])),
231         )
232     }
233 }
234 
235 impl_decoder! { Basic, String, basic_parser() }
236 
237 #[test]
many1_skip_no_errors()238 fn many1_skip_no_errors() {
239     let input = "123\r\n\
240                  456\r\n";
241 
242     let result = run_decoder(input, vec![], Basic::default());
243 
244     assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
245     assert_eq!(result.unwrap(), vec!["123".to_string(), "456".to_string()]);
246 }
247 
248 parser! {
249     type PartialState = AnyPartialState;
250     fn prefix_many_then_parser['a, Input]()(Input) -> String
251         where [ Input: RangeStream<Token = char, Range = &'a str> ]
252     {
253         let integer = from_str(many1::<String, _, _>(digit()));
254         any_partial_state((char('#'), skip_many(char(' ')), integer)
255             .then_partial(|t| {
256                 let c = t.2;
257                 count_min_max(c, c, any())
258             })
259         )
260     }
261 }
262 
263 parser! {
264     type PartialState = AnyPartialState;
265     fn choice_parser['a, Input]()(Input) -> String
266         where [ Input: RangeStream<Token = char, Range = &'a str> ]
267     {
268         any_partial_state(
269             many1(digit())
270                 .or(many1(letter()))
271                 .skip(range(&"\r\n"[..]))
272         )
273     }
274 }
275 
content_length<'a, Input>( ) -> impl Parser<Input, Output = String, PartialState = AnySendPartialState> + 'a where Input: RangeStream<Token = char, Range = &'a str> + 'a, Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,276 fn content_length<'a, Input>(
277 ) -> impl Parser<Input, Output = String, PartialState = AnySendPartialState> + 'a
278 where
279     Input: RangeStream<Token = char, Range = &'a str> + 'a,
280     // Necessary due to rust-lang/rust#24159
281     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
282 {
283     let content_length = range("Content-Length: ").with(
284         range::recognize(skip_many1(digit())).and_then(|digits: &str| {
285             // Convert the error from `.parse` into an error combine understands
286             digits
287                 .parse::<usize>()
288                 .map_err(StreamErrorFor::<Input>::other)
289         }),
290     );
291 
292     any_send_partial_state(
293         (
294             skip_many(range("\r\n")),
295             content_length,
296             range("\r\n\r\n").map(|_| ()),
297         )
298             .then_partial(|&mut (_, message_length, _)| {
299                 take(message_length).map(|bytes: &str| bytes.to_owned())
300             }),
301     )
302 }
303 
304 quickcheck! {
305     fn many1_skip_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
306 
307         let input = "123\r\n\
308                      456\r\n\
309                      1\r\n\
310                      5\r\n\
311                      666666\r\n";
312 
313         let result = run_decoder(input, seq, Basic::default());
314 
315         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
316         assert_eq!(
317             result.unwrap(),
318             vec!["123".to_string(), "456".to_string(), "1".to_string(), "5".to_string(), "666666".to_string()]
319         );
320     }
321 
322     fn prefix_many_then_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
323         impl_decoder!{ TestParser, String, prefix_many_then_parser() }
324 
325         let input = "# 1a\
326                      # 4abcd\
327                      #0\
328                      #3:?a\
329                      #10abcdefghij";
330 
331         let result = run_decoder(input, seq, TestParser::default());
332 
333         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
334         assert_eq!(
335             result.unwrap(),
336             ["a", "abcd", "", ":?a", "abcdefghij"]
337         );
338     }
339 
340     fn choice_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
341         impl_decoder!{ TestParser, String, choice_parser() }
342 
343         let input = "1\r\n\
344                      abcd\r\n\
345                      123\r\n\
346                      abc\r\n\
347                      1232751\r\n";
348 
349         let result = run_decoder(input, seq, TestParser::default());
350 
351         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
352         assert_eq!(
353             result.unwrap(),
354             ["1", "abcd", "123", "abc", "1232751"]
355         );
356     }
357 
358     fn recognize_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
359         impl_decoder!{ TestParser, String,
360             recognize(
361                 (skip_many1(digit()), optional((char('.'), skip_many(digit()))))
362             )
363                 .skip(range(&"\r\n"[..]))
364         }
365 
366         let input = "1.0\r\n\
367                      123.123\r\n\
368                      17824\r\n\
369                      3.14\r\n\
370                      1.\r\n\
371                      2\r\n";
372 
373         let result = run_decoder(input, seq, TestParser::default());
374 
375         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
376         assert_eq!(
377             result.unwrap(),
378             ["1.0", "123.123", "17824", "3.14", "1.", "2"]
379         );
380     }
381 
382     fn recognize_range_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
383         impl_decoder!{ TestParser, String,
384             recognize_with_value(
385                 (skip_many1(digit()), optional((char('.'), skip_many(digit()))))
386             )
387                 .map(|(r, _)| String::from(r))
388                 .skip(range(&"\r\n"[..]))
389         }
390 
391         let input = "1.0\r\n\
392                      123.123\r\n\
393                      17824\r\n\
394                      3.14\r\n\
395                      1.\r\n\
396                      2\r\n";
397 
398         let result = run_decoder(input, seq, TestParser::default());
399 
400         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
401         assert_eq!(
402             result.unwrap(),
403             ["1.0", "123.123", "17824", "3.14", "1.", "2"]
404         );
405     }
406 
407     fn take_while_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
408         impl_decoder!{ TestParser, String,
409             |counter: Rc<Cell<i32>>|
410                 take_while(move |c| { counter.set(counter.get() + 1); c != '\r' })
411                     .map(String::from)
412                     .skip(range("\r\n")),
413             Rc<Cell<i32>>
414         }
415 
416         let input = "1.0\r\n\
417                      123.123\r\n\
418                      17824\r\n\
419                      3.14\r\n\
420                      \r\n\
421                      2\r\n";
422 
423         let counter = Rc::new(Cell::new(0));
424         let result = run_decoder(input, seq, TestParser(Default::default(), counter.clone()));
425 
426         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
427         assert_eq!(
428             result.unwrap(),
429             ["1.0", "123.123", "17824", "3.14", "", "2"]
430         );
431 
432         assert_eq!(counter.get(), 26);
433     }
434 
435     fn take_while1_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
436         impl_decoder!{ TestParser, String,
437             |count: Rc<Cell<i32>>|
438                 take_while1(move |c| { count.set(count.get() + 1); c != '\r' })
439                     .map(String::from)
440                     .skip(range("\r\n")),
441             Rc<Cell<i32>>
442         }
443 
444         let input = "1.0\r\n\
445                      123.123\r\n\
446                      17824\r\n\
447                      3.14\r\n\
448                      1.\r\n\
449                      2\r\n";
450 
451         let counter = Rc::new(Cell::new(0));
452         let result = run_decoder(input, seq, TestParser(Default::default(), counter.clone()));
453 
454         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
455         assert_eq!(
456             result.unwrap(),
457             ["1.0", "123.123", "17824", "3.14", "1.", "2"]
458         );
459 
460         assert_eq!(counter.get(), 28);
461     }
462 
463     fn take_until(seq: PartialWithErrors<GenWouldBlock>) -> () {
464         impl_decoder!{ TestParser, String,
465             |count: Rc<Cell<i32>>|
466                 repeat::take_until(token(',').map(move |_| count.set(count.get() + 1))).skip(token(',')),
467             Rc<Cell<i32>>
468         }
469 
470         let input = "123,456,789,";
471 
472         let counter = Rc::new(Cell::new(0));
473         let result = run_decoder(input, seq, TestParser(Default::default(), counter.clone()));
474 
475         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
476         assert_eq!(
477             result.unwrap(),
478             ["123", "456", "789"]
479         );
480 
481         assert_eq!(counter.get(), 3);
482     }
483 
484     fn take_until_committed(seq: PartialWithErrors<GenWouldBlock>) -> () {
485         impl_decoder!{ TestParser, String,
486             |count: Rc<Cell<i32>>| {
487                 let end = attempt((token(':').map(move |_| count.set(count.get() + 1)), token(':')));
488                 repeat::take_until(end).skip((token(':'), token(':')))
489             },
490             Rc<Cell<i32>>
491         }
492 
493         let input = "123::456::789::";
494 
495         let counter = Rc::new(Cell::new(0));
496         let result = run_decoder(input, seq, TestParser(Default::default(), counter.clone()));
497 
498         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
499         assert_eq!(
500             result.unwrap(),
501             ["123", "456", "789"]
502         );
503 
504         assert_eq!(counter.get(), 3);
505     }
506 
507     fn take_until_range_committed(seq: PartialWithErrors<GenWouldBlock>) -> () {
508         impl_decoder!{ TestParser, String,
509             take_until_range("::").map(String::from).skip((token(':'), token(':')))
510         }
511 
512         let input = "123::456::789::";
513 
514         let result = run_decoder(input, seq, TestParser(Default::default()));
515 
516         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
517         assert_eq!(result.unwrap(), ["123", "456", "789"]);
518     }
519 
520     fn any_send_partial_state_do_not_forget_state(sizes: Vec<usize>, seq: PartialWithErrors<GenWouldBlock>) -> () {
521         impl_decoder!{ TestParser, usize,
522             any_send_partial_state(content_length().map(|bytes| bytes.len()))
523         }
524 
525         let input : String = sizes
526             .iter()
527             .map(|s| {
528                 format!(
529                     "Content-Length: {}\r\n\r\n{}\r\n",
530                     s,
531                     ::std::iter::repeat('a').take(*s).collect::<String>()
532                 )
533             })
534             .collect();
535 
536         let result = run_decoder(input.as_bytes(), seq, TestParser(Default::default()));
537 
538         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
539         assert_eq!(result.unwrap(), sizes);
540     }
541 
542     fn take_fn_test(sizes: Vec<usize>, seq: PartialWithErrors<GenWouldBlock>) -> () {
543         impl_decoder!{ TestParser, usize,
544             take_fn(|s: &str| s.find("\r\n")).map(|bytes: &str| bytes.parse::<usize>().unwrap()).skip(take(2))
545         }
546 
547         let input : String = sizes
548             .iter()
549             .map(|s| {
550                 format!(
551                     "{}\r\n",
552                     s,
553                 )
554             })
555             .collect();
556 
557         let result = run_decoder(input.as_bytes(), seq, TestParser(Default::default()));
558 
559         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
560         assert_eq!(result.unwrap(), sizes);
561     }
562 
563     fn take_until_bytes_test(sizes: Vec<usize>, seq: PartialWithErrors<GenWouldBlock>) -> () {
564         impl_decoder!{ TestParser, usize,
565             take_until_bytes("\r\n".as_bytes())
566                 .map(|bytes: &str| bytes.parse::<usize>().unwrap())
567                 .skip(take(2))
568         }
569 
570         let input : String = sizes
571             .iter()
572             .map(|s| {
573                 format!(
574                     "{}\r\n",
575                     s,
576                 )
577             })
578             .collect();
579 
580         let result = run_decoder(input.as_bytes(), seq, TestParser(Default::default()));
581 
582         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
583         assert_eq!(result.unwrap(), sizes);
584     }
585 
586     fn num_test(ints: Vec<u16>, seq: PartialWithErrors<GenWouldBlock>) -> () {
587         impl_byte_decoder!{ TestParser, u16,
588             num::be_u16()
589                 .skip(take(2))
590         }
591 
592         let input: Vec<u8> = ints.iter()
593             .flat_map(|i| {
594                 let mut v = Vec::new();
595                 v.extend_from_slice(&i.to_be_bytes());
596                 v.extend_from_slice(b"\r\n");
597                 v
598             })
599             .collect();
600 
601         let result = run_decoder(&input, seq, TestParser(Default::default()));
602 
603         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
604         assert_eq!(result.unwrap(), ints);
605     }
606 
607     fn sep_end_by_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
608         impl_decoder!{ TestParser, Vec<String>,
609             repeat::sep_end_by((digit(), digit(), digit()).map(|(a, b, c)| vec![a, b, c].into_iter().collect()), no_partial(string("::")))
610                 .skip(no_partial(string("\r\n")))
611         }
612 
613         let input = "123::456::789::\r\n";
614 
615         let result = run_decoder(&input, seq, TestParser(Default::default()));
616 
617         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
618         assert_eq!(result.unwrap(), vec![vec!["123".to_string(), "456".to_string(), "789".to_string()]]);
619     }
620 }
621 
622 #[test]
skip_count_min_max_test()623 fn skip_count_min_max_test() {
624     let seq = vec![PartialOp::Limited(1)];
625     impl_decoder! { TestParser, String,
626         repeat::skip_count_min_max(1, 2, char('_')).skip(char('.')).map(|_| "".to_string())
627     }
628 
629     let input = "_.";
630 
631     let result = run_decoder(input, seq, TestParser::default());
632 
633     assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
634     assert_eq!(result.unwrap(), [""]);
635 }
636 
637 const WORDS_IN_README: usize = 824;
638 
639 #[test]
decode_std()640 fn decode_std() {
641     quickcheck(
642         (|ops: PartialWithErrors<GenNoErrors>| {
643             let buf = include_bytes!("../README.md");
644 
645             let mut read = PartialRead::new(&buf[..], ops);
646             let mut decoder =
647                 combine::stream::Decoder::<_, combine::stream::PointerOffset<_>>::new();
648             let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
649             assert_eq!(
650                 combine::decode!(
651                     decoder,
652                     read,
653                     {
654                         let word = many1(satisfy(|b| !is_whitespace(b)));
655                         sep_end_by(word, skip_many1(satisfy(is_whitespace)))
656                             .map(|words: Vec<Vec<u8>>| words.len())
657                     },
658                     |input, _| combine::easy::Stream::from(input)
659                 )
660                 .map_err(From::from)
661                 .map_err(
662                     |err: combine::easy::Errors<u8, &[u8], combine::stream::PointerOffset<_>>| err
663                         .map_position(|p| p.0)
664                 ),
665                 Ok(WORDS_IN_README),
666             );
667         }) as fn(_) -> _,
668     )
669 }
670 
671 #[test]
decode_tokio_02()672 fn decode_tokio_02() {
673     quickcheck(
674         (|ops: PartialWithErrors<GenWouldBlock>| {
675             let buf = include_bytes!("../README.md");
676             let runtime = tokio::runtime::Builder::new_current_thread()
677                 .build()
678                 .unwrap();
679             runtime.block_on(async {
680                 let mut read = PartialAsyncRead::new(&buf[..], ops);
681                 let mut decoder =
682                     combine::stream::Decoder::<_, combine::stream::PointerOffset<[u8]>>::new();
683                 let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
684                 assert_eq!(
685                     combine::decode_tokio_02!(
686                         decoder,
687                         read,
688                         {
689                             let word = many1(satisfy(|b| !is_whitespace(b)));
690                             sep_end_by(word, skip_many1(satisfy(is_whitespace)))
691                                 .map(|words: Vec<Vec<u8>>| words.len())
692                         },
693                         |input, _| combine::easy::Stream::from(input)
694                     )
695                     .map_err(From::from)
696                     .map_err(
697                         |err: combine::easy::Errors<u8, &[u8], _>| err.map_range(|r| r.to_owned())
698                     )
699                     .map_err(|err| err.map_position(|p| p.translate_position(&decoder.buffer()))),
700                     Ok(WORDS_IN_README),
701                 );
702             })
703         }) as fn(_) -> _,
704     )
705 }
706 
707 #[test]
decode_tokio_03()708 fn decode_tokio_03() {
709     quickcheck(
710         (|ops: PartialWithErrors<GenWouldBlock>| {
711             let buf = include_bytes!("../README.md");
712             let runtime = tokio::runtime::Builder::new_current_thread()
713                 .build()
714                 .unwrap();
715             runtime.block_on(async {
716                 let mut read = PartialAsyncRead::new(&buf[..], ops);
717                 let mut decoder =
718                     combine::stream::Decoder::<_, combine::stream::PointerOffset<[u8]>>::new();
719                 let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
720                 assert_eq!(
721                     combine::decode_tokio_03!(
722                         decoder,
723                         read,
724                         {
725                             let word = many1(satisfy(|b| !is_whitespace(b)));
726                             sep_end_by(word, skip_many1(satisfy(is_whitespace)))
727                                 .map(|words: Vec<Vec<u8>>| words.len())
728                         },
729                         |input, _| combine::easy::Stream::from(input)
730                     )
731                     .map_err(From::from)
732                     .map_err(
733                         |err: combine::easy::Errors<u8, &[u8], _>| err.map_range(|r| r.to_owned())
734                     )
735                     .map_err(|err| err.map_position(|p| p.translate_position(&decoder.buffer()))),
736                     Ok(WORDS_IN_README),
737                 );
738             })
739         }) as fn(_) -> _,
740     )
741 }
742 
743 #[test]
decode_tokio()744 fn decode_tokio() {
745     quickcheck(
746         (|ops: PartialWithErrors<GenWouldBlock>| {
747             let buf = include_bytes!("../README.md");
748             let runtime = tokio::runtime::Builder::new_current_thread()
749                 .build()
750                 .unwrap();
751             runtime.block_on(async {
752                 let mut read = PartialAsyncRead::new(&buf[..], ops);
753                 let mut decoder =
754                     combine::stream::Decoder::<_, combine::stream::PointerOffset<[u8]>>::new();
755                 let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
756                 assert_eq!(
757                     combine::decode_tokio!(
758                         decoder,
759                         read,
760                         {
761                             let word = many1(satisfy(|b| !is_whitespace(b)));
762                             sep_end_by(word, skip_many1(satisfy(is_whitespace)))
763                                 .map(|words: Vec<Vec<u8>>| words.len())
764                         },
765                         |input, _| combine::easy::Stream::from(input)
766                     )
767                     .map_err(From::from)
768                     .map_err(
769                         |err: combine::easy::Errors<u8, &[u8], _>| err.map_range(|r| r.to_owned())
770                     )
771                     .map_err(|err| err.map_position(|p| p.translate_position(&decoder.buffer()))),
772                     Ok(WORDS_IN_README),
773                 );
774             })
775         }) as fn(_) -> _,
776     )
777 }
778 
779 #[test]
decode_async_std()780 fn decode_async_std() {
781     quickcheck(
782         (|ops: PartialWithErrors<GenWouldBlock>| {
783             let buf = include_bytes!("../README.md");
784             async_std::task::block_on(async {
785                 let mut read = FuturesPartialAsyncRead::new(&buf[..], ops);
786                 let mut decoder =
787                     combine::stream::Decoder::<_, combine::stream::PointerOffset<[u8]>>::new();
788                 let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
789                 assert_eq!(
790                     combine::decode_futures_03!(
791                         decoder,
792                         read,
793                         {
794                             let word = many1(satisfy(|b| !is_whitespace(b)));
795                             sep_end_by(word, skip_many1(satisfy(is_whitespace)))
796                                 .map(|words: Vec<Vec<u8>>| words.len())
797                         },
798                         |input, _| combine::easy::Stream::from(input),
799                     )
800                     .map_err(From::from)
801                     .map_err(|err: combine::easy::Errors<u8, &[u8], _>| err),
802                     Ok(WORDS_IN_README),
803                 );
804             })
805         }) as fn(_) -> _,
806     )
807 }
808 
809 #[tokio::test]
decode_loop()810 async fn decode_loop() {
811     use tokio::fs::File;
812 
813     use combine::{
814         decode_tokio, many1, satisfy, skip_many1,
815         stream::{buf_reader::BufReader, Decoder},
816     };
817     let mut read = BufReader::new(File::open("README.md").await.unwrap());
818     let mut decoder = Decoder::new_bufferless();
819     let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
820 
821     let mut count = 0;
822     loop {
823         // async block suppresses a warning about duplicate label
824         if async {
825             decode_tokio!(
826                 decoder,
827                 read,
828                 many1(satisfy(|b| !is_whitespace(b))),
829                 |input, _position| combine::easy::Stream::from(input),
830             )
831             .is_err()
832         }
833         .await
834         {
835             break;
836         }
837 
838         count += 1;
839 
840         {
841             if decode_tokio!(
842                 decoder,
843                 read,
844                 skip_many1(satisfy(is_whitespace)),
845                 |input, _position| combine::easy::Stream::from(input),
846             )
847             .is_err()
848             {
849                 break;
850             }
851         }
852     }
853     assert_eq!(824, count);
854 }
855