1 extern crate flate2;
2 extern crate futures;
3 extern crate tokio_io;
4 
5 use flate2::read::{GzDecoder, MultiGzDecoder};
6 use futures::prelude::*;
7 use futures::task;
8 use std::cmp;
9 use std::fs::File;
10 use std::io::{self, Read};
11 use tokio_io::io::read_to_end;
12 use tokio_io::AsyncRead;
13 
14 struct BadReader<T> {
15     reader: T,
16     x: bool,
17 }
18 
19 impl<T> BadReader<T> {
new(reader: T) -> BadReader<T>20     fn new(reader: T) -> BadReader<T> {
21         BadReader { reader, x: true }
22     }
23 }
24 
25 impl<T: Read> Read for BadReader<T> {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>26     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
27         if self.x {
28             self.x = false;
29             let len = cmp::min(buf.len(), 1);
30             self.reader.read(&mut buf[..len])
31         } else {
32             self.x = true;
33             Err(io::ErrorKind::WouldBlock.into())
34         }
35     }
36 }
37 
38 struct AssertAsync<T>(T);
39 
40 impl<T: Read> Read for AssertAsync<T> {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>41     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
42         self.0.read(buf)
43     }
44 }
45 
46 impl<T: Read> AsyncRead for AssertAsync<T> {}
47 
48 struct AlwaysNotify<T>(T);
49 
50 impl<T: Future> Future for AlwaysNotify<T> {
51     type Item = T::Item;
52     type Error = T::Error;
53 
poll(&mut self) -> Poll<Self::Item, Self::Error>54     fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
55         let ret = self.0.poll();
56         if let Ok(Async::NotReady) = &ret {
57             task::current().notify();
58         }
59         ret
60     }
61 }
62 
63 #[test]
test_gz_asyncread()64 fn test_gz_asyncread() {
65     let f = File::open("tests/good-file.gz").unwrap();
66 
67     let fut = read_to_end(AssertAsync(GzDecoder::new(BadReader::new(f))), Vec::new());
68     let (_, content) = AlwaysNotify(fut).wait().unwrap();
69 
70     let mut expected = Vec::new();
71     File::open("tests/good-file.txt")
72         .unwrap()
73         .read_to_end(&mut expected)
74         .unwrap();
75 
76     assert_eq!(content, expected);
77 }
78 
79 #[test]
test_multi_gz_asyncread()80 fn test_multi_gz_asyncread() {
81     let f = File::open("tests/multi.gz").unwrap();
82 
83     let fut = read_to_end(
84         AssertAsync(MultiGzDecoder::new(BadReader::new(f))),
85         Vec::new(),
86     );
87     let (_, content) = AlwaysNotify(fut).wait().unwrap();
88 
89     let mut expected = Vec::new();
90     File::open("tests/multi.txt")
91         .unwrap()
92         .read_to_end(&mut expected)
93         .unwrap();
94 
95     assert_eq!(content, expected);
96 }
97