1 use futures::executor::block_on;
2 use futures::future::{Future, FutureExt};
3 use futures::io::{AsyncSeek, AsyncSeekExt, AsyncWrite, AsyncWriteExt, BufWriter, SeekFrom};
4 use futures::task::{Context, Poll};
5 use futures_test::task::noop_context;
6 use std::io::{self, Cursor};
7 use std::pin::Pin;
8 
9 #[test]
buf_writer()10 fn buf_writer() {
11     let mut writer = BufWriter::with_capacity(2, Vec::new());
12 
13     block_on(writer.write(&[0, 1])).unwrap();
14     assert_eq!(writer.buffer(), []);
15     assert_eq!(*writer.get_ref(), [0, 1]);
16 
17     block_on(writer.write(&[2])).unwrap();
18     assert_eq!(writer.buffer(), [2]);
19     assert_eq!(*writer.get_ref(), [0, 1]);
20 
21     block_on(writer.write(&[3])).unwrap();
22     assert_eq!(writer.buffer(), [2, 3]);
23     assert_eq!(*writer.get_ref(), [0, 1]);
24 
25     block_on(writer.flush()).unwrap();
26     assert_eq!(writer.buffer(), []);
27     assert_eq!(*writer.get_ref(), [0, 1, 2, 3]);
28 
29     block_on(writer.write(&[4])).unwrap();
30     block_on(writer.write(&[5])).unwrap();
31     assert_eq!(writer.buffer(), [4, 5]);
32     assert_eq!(*writer.get_ref(), [0, 1, 2, 3]);
33 
34     block_on(writer.write(&[6])).unwrap();
35     assert_eq!(writer.buffer(), [6]);
36     assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5]);
37 
38     block_on(writer.write(&[7, 8])).unwrap();
39     assert_eq!(writer.buffer(), []);
40     assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8]);
41 
42     block_on(writer.write(&[9, 10, 11])).unwrap();
43     assert_eq!(writer.buffer(), []);
44     assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
45 
46     block_on(writer.flush()).unwrap();
47     assert_eq!(writer.buffer(), []);
48     assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
49 }
50 
51 #[test]
buf_writer_inner_flushes()52 fn buf_writer_inner_flushes() {
53     let mut w = BufWriter::with_capacity(3, Vec::new());
54     block_on(w.write(&[0, 1])).unwrap();
55     assert_eq!(*w.get_ref(), []);
56     block_on(w.flush()).unwrap();
57     let w = w.into_inner();
58     assert_eq!(w, [0, 1]);
59 }
60 
61 #[test]
buf_writer_seek()62 fn buf_writer_seek() {
63     // FIXME: when https://github.com/rust-lang-nursery/futures-rs/issues/1510 fixed,
64     // use `Vec::new` instead of `vec![0; 8]`.
65     let mut w = BufWriter::with_capacity(3, Cursor::new(vec![0; 8]));
66     block_on(w.write_all(&[0, 1, 2, 3, 4, 5])).unwrap();
67     block_on(w.write_all(&[6, 7])).unwrap();
68     assert_eq!(block_on(w.seek(SeekFrom::Current(0))).ok(), Some(8));
69     assert_eq!(&w.get_ref().get_ref()[..], &[0, 1, 2, 3, 4, 5, 6, 7][..]);
70     assert_eq!(block_on(w.seek(SeekFrom::Start(2))).ok(), Some(2));
71     block_on(w.write_all(&[8, 9])).unwrap();
72     block_on(w.flush()).unwrap();
73     assert_eq!(&w.into_inner().into_inner()[..], &[0, 1, 8, 9, 4, 5, 6, 7]);
74 }
75 
76 struct MaybePending {
77     inner: Vec<u8>,
78     ready: bool,
79 }
80 
81 impl MaybePending {
new(inner: Vec<u8>) -> Self82     fn new(inner: Vec<u8>) -> Self {
83         Self { inner, ready: false }
84     }
85 }
86 
87 impl AsyncWrite for MaybePending {
poll_write( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll<io::Result<usize>>88     fn poll_write(
89         mut self: Pin<&mut Self>,
90         cx: &mut Context<'_>,
91         buf: &[u8],
92     ) -> Poll<io::Result<usize>> {
93         if self.ready {
94             self.ready = false;
95             Pin::new(&mut self.inner).poll_write(cx, buf)
96         } else {
97             self.ready = true;
98             Poll::Pending
99         }
100     }
101 
poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>>102     fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
103         Pin::new(&mut self.inner).poll_flush(cx)
104     }
105 
poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>>106     fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
107         Pin::new(&mut self.inner).poll_close(cx)
108     }
109 }
110 
run<F: Future + Unpin>(mut f: F) -> F::Output111 fn run<F: Future + Unpin>(mut f: F) -> F::Output {
112     let mut cx = noop_context();
113     loop {
114         if let Poll::Ready(x) = f.poll_unpin(&mut cx) {
115             return x;
116         }
117     }
118 }
119 
120 #[test]
maybe_pending_buf_writer()121 fn maybe_pending_buf_writer() {
122     let mut writer = BufWriter::with_capacity(2, MaybePending::new(Vec::new()));
123 
124     run(writer.write(&[0, 1])).unwrap();
125     assert_eq!(writer.buffer(), []);
126     assert_eq!(&writer.get_ref().inner, &[0, 1]);
127 
128     run(writer.write(&[2])).unwrap();
129     assert_eq!(writer.buffer(), [2]);
130     assert_eq!(&writer.get_ref().inner, &[0, 1]);
131 
132     run(writer.write(&[3])).unwrap();
133     assert_eq!(writer.buffer(), [2, 3]);
134     assert_eq!(&writer.get_ref().inner, &[0, 1]);
135 
136     run(writer.flush()).unwrap();
137     assert_eq!(writer.buffer(), []);
138     assert_eq!(&writer.get_ref().inner, &[0, 1, 2, 3]);
139 
140     run(writer.write(&[4])).unwrap();
141     run(writer.write(&[5])).unwrap();
142     assert_eq!(writer.buffer(), [4, 5]);
143     assert_eq!(&writer.get_ref().inner, &[0, 1, 2, 3]);
144 
145     run(writer.write(&[6])).unwrap();
146     assert_eq!(writer.buffer(), [6]);
147     assert_eq!(writer.get_ref().inner, &[0, 1, 2, 3, 4, 5]);
148 
149     run(writer.write(&[7, 8])).unwrap();
150     assert_eq!(writer.buffer(), []);
151     assert_eq!(writer.get_ref().inner, &[0, 1, 2, 3, 4, 5, 6, 7, 8]);
152 
153     run(writer.write(&[9, 10, 11])).unwrap();
154     assert_eq!(writer.buffer(), []);
155     assert_eq!(writer.get_ref().inner, &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
156 
157     run(writer.flush()).unwrap();
158     assert_eq!(writer.buffer(), []);
159     assert_eq!(&writer.get_ref().inner, &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
160 }
161 
162 #[test]
maybe_pending_buf_writer_inner_flushes()163 fn maybe_pending_buf_writer_inner_flushes() {
164     let mut w = BufWriter::with_capacity(3, MaybePending::new(Vec::new()));
165     run(w.write(&[0, 1])).unwrap();
166     assert_eq!(&w.get_ref().inner, &[]);
167     run(w.flush()).unwrap();
168     let w = w.into_inner().inner;
169     assert_eq!(w, [0, 1]);
170 }
171 
172 
173 struct MaybePendingSeek {
174     inner: Cursor<Vec<u8>>,
175     ready_write: bool,
176     ready_seek: bool,
177 }
178 
179 impl MaybePendingSeek {
new(inner: Vec<u8>) -> Self180     fn new(inner: Vec<u8>) -> Self {
181         Self { inner: Cursor::new(inner), ready_write: false, ready_seek: false }
182     }
183 }
184 
185 impl AsyncWrite for MaybePendingSeek {
poll_write( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll<io::Result<usize>>186     fn poll_write(
187         mut self: Pin<&mut Self>,
188         cx: &mut Context<'_>,
189         buf: &[u8],
190     ) -> Poll<io::Result<usize>> {
191         if self.ready_write {
192             self.ready_write = false;
193             Pin::new(&mut self.inner).poll_write(cx, buf)
194         } else {
195             self.ready_write = true;
196             Poll::Pending
197         }
198     }
199 
poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>>200     fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
201         Pin::new(&mut self.inner).poll_flush(cx)
202     }
203 
poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>>204     fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
205         Pin::new(&mut self.inner).poll_close(cx)
206     }
207 }
208 
209 impl AsyncSeek for MaybePendingSeek {
poll_seek(mut self: Pin<&mut Self>, cx: &mut Context<'_>, pos: SeekFrom) -> Poll<io::Result<u64>>210     fn poll_seek(mut self: Pin<&mut Self>, cx: &mut Context<'_>, pos: SeekFrom)
211         -> Poll<io::Result<u64>>
212     {
213         if self.ready_seek {
214             self.ready_seek = false;
215             Pin::new(&mut self.inner).poll_seek(cx, pos)
216         } else {
217             self.ready_seek = true;
218             Poll::Pending
219         }
220     }
221 }
222 
223 #[test]
maybe_pending_buf_writer_seek()224 fn maybe_pending_buf_writer_seek() {
225     // FIXME: when https://github.com/rust-lang-nursery/futures-rs/issues/1510 fixed,
226     // use `Vec::new` instead of `vec![0; 8]`.
227     let mut w = BufWriter::with_capacity(3, MaybePendingSeek::new(vec![0; 8]));
228     run(w.write_all(&[0, 1, 2, 3, 4, 5])).unwrap();
229     run(w.write_all(&[6, 7])).unwrap();
230     assert_eq!(run(w.seek(SeekFrom::Current(0))).ok(), Some(8));
231     assert_eq!(&w.get_ref().inner.get_ref()[..], &[0, 1, 2, 3, 4, 5, 6, 7][..]);
232     assert_eq!(run(w.seek(SeekFrom::Start(2))).ok(), Some(2));
233     run(w.write_all(&[8, 9])).unwrap();
234     run(w.flush()).unwrap();
235     assert_eq!(&w.into_inner().inner.into_inner()[..], &[0, 1, 8, 9, 4, 5, 6, 7]);
236 }
237