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,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 {
281     let content_length = range("Content-Length: ").with(
282         range::recognize(skip_many1(digit())).and_then(|digits: &str| {
283             // Convert the error from `.parse` into an error combine understands
284             digits
285                 .parse::<usize>()
286                 .map_err(StreamErrorFor::<Input>::other)
287         }),
288     );
289 
290     any_send_partial_state(
291         (
292             skip_many(range("\r\n")),
293             content_length,
294             range("\r\n\r\n").map(|_| ()),
295         )
296             .then_partial(|&mut (_, message_length, _)| {
297                 take(message_length).map(|bytes: &str| bytes.to_owned())
298             }),
299     )
300 }
301 
302 quickcheck! {
303     fn many1_skip_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
304 
305         let input = "123\r\n\
306                      456\r\n\
307                      1\r\n\
308                      5\r\n\
309                      666666\r\n";
310 
311         let result = run_decoder(input, seq, Basic::default());
312 
313         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
314         assert_eq!(
315             result.unwrap(),
316             vec!["123".to_string(), "456".to_string(), "1".to_string(), "5".to_string(), "666666".to_string()]
317         );
318     }
319 
320     fn prefix_many_then_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
321         impl_decoder!{ TestParser, String, prefix_many_then_parser() }
322 
323         let input = "# 1a\
324                      # 4abcd\
325                      #0\
326                      #3:?a\
327                      #10abcdefghij";
328 
329         let result = run_decoder(input, seq, TestParser::default());
330 
331         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
332         assert_eq!(
333             result.unwrap(),
334             ["a", "abcd", "", ":?a", "abcdefghij"]
335         );
336     }
337 
338     fn choice_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
339         impl_decoder!{ TestParser, String, choice_parser() }
340 
341         let input = "1\r\n\
342                      abcd\r\n\
343                      123\r\n\
344                      abc\r\n\
345                      1232751\r\n";
346 
347         let result = run_decoder(input, seq, TestParser::default());
348 
349         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
350         assert_eq!(
351             result.unwrap(),
352             ["1", "abcd", "123", "abc", "1232751"]
353         );
354     }
355 
356     fn recognize_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
357         impl_decoder!{ TestParser, String,
358             recognize(
359                 (skip_many1(digit()), optional((char('.'), skip_many(digit()))))
360             )
361                 .skip(range(&"\r\n"[..]))
362         }
363 
364         let input = "1.0\r\n\
365                      123.123\r\n\
366                      17824\r\n\
367                      3.14\r\n\
368                      1.\r\n\
369                      2\r\n";
370 
371         let result = run_decoder(input, seq, TestParser::default());
372 
373         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
374         assert_eq!(
375             result.unwrap(),
376             ["1.0", "123.123", "17824", "3.14", "1.", "2"]
377         );
378     }
379 
380     fn recognize_range_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
381         impl_decoder!{ TestParser, String,
382             recognize_with_value(
383                 (skip_many1(digit()), optional((char('.'), skip_many(digit()))))
384             )
385                 .map(|(r, _)| String::from(r))
386                 .skip(range(&"\r\n"[..]))
387         }
388 
389         let input = "1.0\r\n\
390                      123.123\r\n\
391                      17824\r\n\
392                      3.14\r\n\
393                      1.\r\n\
394                      2\r\n";
395 
396         let result = run_decoder(input, seq, TestParser::default());
397 
398         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
399         assert_eq!(
400             result.unwrap(),
401             ["1.0", "123.123", "17824", "3.14", "1.", "2"]
402         );
403     }
404 
405     fn take_while_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
406         impl_decoder!{ TestParser, String,
407             |counter: Rc<Cell<i32>>|
408                 take_while(move |c| { counter.set(counter.get() + 1); c != '\r' })
409                     .map(String::from)
410                     .skip(range("\r\n")),
411             Rc<Cell<i32>>
412         }
413 
414         let input = "1.0\r\n\
415                      123.123\r\n\
416                      17824\r\n\
417                      3.14\r\n\
418                      \r\n\
419                      2\r\n";
420 
421         let counter = Rc::new(Cell::new(0));
422         let result = run_decoder(input, seq, TestParser(Default::default(), counter.clone()));
423 
424         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
425         assert_eq!(
426             result.unwrap(),
427             ["1.0", "123.123", "17824", "3.14", "", "2"]
428         );
429 
430         assert_eq!(counter.get(), 26);
431     }
432 
433     fn take_while1_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
434         impl_decoder!{ TestParser, String,
435             |count: Rc<Cell<i32>>|
436                 take_while1(move |c| { count.set(count.get() + 1); c != '\r' })
437                     .map(String::from)
438                     .skip(range("\r\n")),
439             Rc<Cell<i32>>
440         }
441 
442         let input = "1.0\r\n\
443                      123.123\r\n\
444                      17824\r\n\
445                      3.14\r\n\
446                      1.\r\n\
447                      2\r\n";
448 
449         let counter = Rc::new(Cell::new(0));
450         let result = run_decoder(input, seq, TestParser(Default::default(), counter.clone()));
451 
452         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
453         assert_eq!(
454             result.unwrap(),
455             ["1.0", "123.123", "17824", "3.14", "1.", "2"]
456         );
457 
458         assert_eq!(counter.get(), 28);
459     }
460 
461     fn take_until(seq: PartialWithErrors<GenWouldBlock>) -> () {
462         impl_decoder!{ TestParser, String,
463             |count: Rc<Cell<i32>>|
464                 repeat::take_until(token(',').map(move |_| count.set(count.get() + 1))).skip(token(',')),
465             Rc<Cell<i32>>
466         }
467 
468         let input = "123,456,789,";
469 
470         let counter = Rc::new(Cell::new(0));
471         let result = run_decoder(input, seq, TestParser(Default::default(), counter.clone()));
472 
473         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
474         assert_eq!(
475             result.unwrap(),
476             ["123", "456", "789"]
477         );
478 
479         assert_eq!(counter.get(), 3);
480     }
481 
482     fn take_until_committed(seq: PartialWithErrors<GenWouldBlock>) -> () {
483         impl_decoder!{ TestParser, String,
484             |count: Rc<Cell<i32>>| {
485                 let end = attempt((token(':').map(move |_| count.set(count.get() + 1)), token(':')));
486                 repeat::take_until(end).skip((token(':'), token(':')))
487             },
488             Rc<Cell<i32>>
489         }
490 
491         let input = "123::456::789::";
492 
493         let counter = Rc::new(Cell::new(0));
494         let result = run_decoder(input, seq, TestParser(Default::default(), counter.clone()));
495 
496         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
497         assert_eq!(
498             result.unwrap(),
499             ["123", "456", "789"]
500         );
501 
502         assert_eq!(counter.get(), 3);
503     }
504 
505     fn take_until_range_committed(seq: PartialWithErrors<GenWouldBlock>) -> () {
506         impl_decoder!{ TestParser, String,
507             take_until_range("::").map(String::from).skip((token(':'), token(':')))
508         }
509 
510         let input = "123::456::789::";
511 
512         let result = run_decoder(input, seq, TestParser(Default::default()));
513 
514         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
515         assert_eq!(result.unwrap(), ["123", "456", "789"]);
516     }
517 
518     fn any_send_partial_state_do_not_forget_state(sizes: Vec<usize>, seq: PartialWithErrors<GenWouldBlock>) -> () {
519         impl_decoder!{ TestParser, usize,
520             any_send_partial_state(content_length().map(|bytes| bytes.len()))
521         }
522 
523         let input : String = sizes
524             .iter()
525             .map(|s| {
526                 format!(
527                     "Content-Length: {}\r\n\r\n{}\r\n",
528                     s,
529                     ::std::iter::repeat('a').take(*s).collect::<String>()
530                 )
531             })
532             .collect();
533 
534         let result = run_decoder(input.as_bytes(), seq, TestParser(Default::default()));
535 
536         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
537         assert_eq!(result.unwrap(), sizes);
538     }
539 
540     fn take_fn_test(sizes: Vec<usize>, seq: PartialWithErrors<GenWouldBlock>) -> () {
541         impl_decoder!{ TestParser, usize,
542             take_fn(|s: &str| s.find("\r\n")).map(|bytes: &str| bytes.parse::<usize>().unwrap()).skip(take(2))
543         }
544 
545         let input : String = sizes
546             .iter()
547             .map(|s| {
548                 format!(
549                     "{}\r\n",
550                     s,
551                 )
552             })
553             .collect();
554 
555         let result = run_decoder(input.as_bytes(), seq, TestParser(Default::default()));
556 
557         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
558         assert_eq!(result.unwrap(), sizes);
559     }
560 
561     fn take_until_bytes_test(sizes: Vec<usize>, seq: PartialWithErrors<GenWouldBlock>) -> () {
562         impl_decoder!{ TestParser, usize,
563             take_until_bytes("\r\n".as_bytes())
564                 .map(|bytes: &str| bytes.parse::<usize>().unwrap())
565                 .skip(take(2))
566         }
567 
568         let input : String = sizes
569             .iter()
570             .map(|s| {
571                 format!(
572                     "{}\r\n",
573                     s,
574                 )
575             })
576             .collect();
577 
578         let result = run_decoder(input.as_bytes(), seq, TestParser(Default::default()));
579 
580         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
581         assert_eq!(result.unwrap(), sizes);
582     }
583 
584     fn num_test(ints: Vec<u16>, seq: PartialWithErrors<GenWouldBlock>) -> () {
585         impl_byte_decoder!{ TestParser, u16,
586             num::be_u16()
587                 .skip(take(2))
588         }
589 
590         let input: Vec<u8> = ints.iter()
591             .flat_map(|i| {
592                 let mut v = Vec::new();
593                 v.extend_from_slice(&i.to_be_bytes());
594                 v.extend_from_slice(b"\r\n");
595                 v
596             })
597             .collect();
598 
599         let result = run_decoder(&input, seq, TestParser(Default::default()));
600 
601         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
602         assert_eq!(result.unwrap(), ints);
603     }
604 
605     fn sep_end_by_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
606         impl_decoder!{ TestParser, Vec<String>,
607             repeat::sep_end_by((digit(), digit(), digit()).map(|(a, b, c)| vec![a, b, c].into_iter().collect()), no_partial(string("::")))
608                 .skip(no_partial(string("\r\n")))
609         }
610 
611         let input = "123::456::789::\r\n";
612 
613         let result = run_decoder(&input, seq, TestParser(Default::default()));
614 
615         assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
616         assert_eq!(result.unwrap(), vec![vec!["123".to_string(), "456".to_string(), "789".to_string()]]);
617     }
618 }
619 
620 #[test]
skip_count_min_max_test()621 fn skip_count_min_max_test() {
622     let seq = vec![PartialOp::Limited(1)];
623     impl_decoder! { TestParser, String,
624         repeat::skip_count_min_max(1, 2, char('_')).skip(char('.')).map(|_| "".to_string())
625     }
626 
627     let input = "_.";
628 
629     let result = run_decoder(input, seq, TestParser::default());
630 
631     assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
632     assert_eq!(result.unwrap(), [""]);
633 }
634 
635 const WORDS_IN_README: usize = 773;
636 
637 #[test]
decode_std()638 fn decode_std() {
639     quickcheck(
640         (|ops: PartialWithErrors<GenNoErrors>| {
641             let buf = include_bytes!("../README.md");
642 
643             let mut read = PartialRead::new(&buf[..], ops);
644             let mut decoder =
645                 combine::stream::Decoder::<_, combine::stream::PointerOffset<_>>::new();
646             let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
647             assert_eq!(
648                 combine::decode!(
649                     decoder,
650                     read,
651                     {
652                         let word = many1(satisfy(|b| !is_whitespace(b)));
653                         sep_end_by(word, skip_many1(satisfy(is_whitespace)))
654                             .map(|words: Vec<Vec<u8>>| words.len())
655                     },
656                     |input, _| combine::easy::Stream::from(input)
657                 )
658                 .map_err(From::from)
659                 .map_err(
660                     |err: combine::easy::Errors<u8, &[u8], combine::stream::PointerOffset<_>>| err
661                         .map_position(|p| p.0)
662                 ),
663                 Ok(WORDS_IN_README),
664             );
665         }) as fn(_) -> _,
666     )
667 }
668 
669 #[test]
decode_tokio_02()670 fn decode_tokio_02() {
671     quickcheck(
672         (|ops: PartialWithErrors<GenWouldBlock>| {
673             let buf = include_bytes!("../README.md");
674             let runtime = tokio::runtime::Builder::new_current_thread()
675                 .build()
676                 .unwrap();
677             runtime.block_on(async {
678                 let mut read = PartialAsyncRead::new(&buf[..], ops);
679                 let mut decoder =
680                     combine::stream::Decoder::<_, combine::stream::PointerOffset<[u8]>>::new();
681                 let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
682                 assert_eq!(
683                     combine::decode_tokio_02!(
684                         decoder,
685                         read,
686                         {
687                             let word = many1(satisfy(|b| !is_whitespace(b)));
688                             sep_end_by(word, skip_many1(satisfy(is_whitespace)))
689                                 .map(|words: Vec<Vec<u8>>| words.len())
690                         },
691                         |input, _| combine::easy::Stream::from(input)
692                     )
693                     .map_err(From::from)
694                     .map_err(
695                         |err: combine::easy::Errors<u8, &[u8], _>| err.map_range(|r| r.to_owned())
696                     )
697                     .map_err(|err| err.map_position(|p| p.translate_position(&decoder.buffer()))),
698                     Ok(WORDS_IN_README),
699                 );
700             })
701         }) as fn(_) -> _,
702     )
703 }
704 
705 #[test]
decode_tokio_03()706 fn decode_tokio_03() {
707     quickcheck(
708         (|ops: PartialWithErrors<GenWouldBlock>| {
709             let buf = include_bytes!("../README.md");
710             let runtime = tokio::runtime::Builder::new_current_thread()
711                 .build()
712                 .unwrap();
713             runtime.block_on(async {
714                 let mut read = PartialAsyncRead::new(&buf[..], ops);
715                 let mut decoder =
716                     combine::stream::Decoder::<_, combine::stream::PointerOffset<[u8]>>::new();
717                 let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
718                 assert_eq!(
719                     combine::decode_tokio_03!(
720                         decoder,
721                         read,
722                         {
723                             let word = many1(satisfy(|b| !is_whitespace(b)));
724                             sep_end_by(word, skip_many1(satisfy(is_whitespace)))
725                                 .map(|words: Vec<Vec<u8>>| words.len())
726                         },
727                         |input, _| combine::easy::Stream::from(input)
728                     )
729                     .map_err(From::from)
730                     .map_err(
731                         |err: combine::easy::Errors<u8, &[u8], _>| err.map_range(|r| r.to_owned())
732                     )
733                     .map_err(|err| err.map_position(|p| p.translate_position(&decoder.buffer()))),
734                     Ok(WORDS_IN_README),
735                 );
736             })
737         }) as fn(_) -> _,
738     )
739 }
740 
741 #[test]
decode_tokio()742 fn decode_tokio() {
743     quickcheck(
744         (|ops: PartialWithErrors<GenWouldBlock>| {
745             let buf = include_bytes!("../README.md");
746             let runtime = tokio::runtime::Builder::new_current_thread()
747                 .build()
748                 .unwrap();
749             runtime.block_on(async {
750                 let mut read = PartialAsyncRead::new(&buf[..], ops);
751                 let mut decoder =
752                     combine::stream::Decoder::<_, combine::stream::PointerOffset<[u8]>>::new();
753                 let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
754                 assert_eq!(
755                     combine::decode_tokio!(
756                         decoder,
757                         read,
758                         {
759                             let word = many1(satisfy(|b| !is_whitespace(b)));
760                             sep_end_by(word, skip_many1(satisfy(is_whitespace)))
761                                 .map(|words: Vec<Vec<u8>>| words.len())
762                         },
763                         |input, _| combine::easy::Stream::from(input)
764                     )
765                     .map_err(From::from)
766                     .map_err(
767                         |err: combine::easy::Errors<u8, &[u8], _>| err.map_range(|r| r.to_owned())
768                     )
769                     .map_err(|err| err.map_position(|p| p.translate_position(&decoder.buffer()))),
770                     Ok(WORDS_IN_README),
771                 );
772             })
773         }) as fn(_) -> _,
774     )
775 }
776 
777 #[test]
decode_async_std()778 fn decode_async_std() {
779     quickcheck(
780         (|ops: PartialWithErrors<GenWouldBlock>| {
781             let buf = include_bytes!("../README.md");
782             async_std::task::block_on(async {
783                 let mut read = FuturesPartialAsyncRead::new(&buf[..], ops);
784                 let mut decoder =
785                     combine::stream::Decoder::<_, combine::stream::PointerOffset<[u8]>>::new();
786                 let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
787                 assert_eq!(
788                     combine::decode_futures_03!(
789                         decoder,
790                         read,
791                         {
792                             let word = many1(satisfy(|b| !is_whitespace(b)));
793                             sep_end_by(word, skip_many1(satisfy(is_whitespace)))
794                                 .map(|words: Vec<Vec<u8>>| words.len())
795                         },
796                         |input, _| combine::easy::Stream::from(input),
797                     )
798                     .map_err(From::from)
799                     .map_err(|err: combine::easy::Errors<u8, &[u8], _>| err),
800                     Ok(WORDS_IN_README),
801                 );
802             })
803         }) as fn(_) -> _,
804     )
805 }
806 
807 #[tokio::test]
decode_loop()808 async fn decode_loop() {
809     use tokio::fs::File;
810 
811     use combine::{
812         decode_tokio, many1, satisfy, skip_many1,
813         stream::{buf_reader::BufReader, Decoder},
814     };
815     let mut read = BufReader::new(File::open("README.md").await.unwrap());
816     let mut decoder = Decoder::new_bufferless();
817     let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
818 
819     let mut count = 0;
820     loop {
821         // async block suppresses a warning about duplicate label
822         if async {
823             decode_tokio!(
824                 decoder,
825                 read,
826                 many1(satisfy(|b| !is_whitespace(b))),
827                 |input, _position| combine::easy::Stream::from(input),
828             )
829             .is_err()
830         }
831         .await
832         {
833             break;
834         }
835 
836         count += 1;
837 
838         {
839             if decode_tokio!(
840                 decoder,
841                 read,
842                 skip_many1(satisfy(is_whitespace)),
843                 |input, _position| combine::easy::Stream::from(input),
844             )
845             .is_err()
846             {
847                 break;
848             }
849         }
850     }
851     assert_eq!(WORDS_IN_README, count);
852 }
853