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