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