1use std::future::Future;
5use std::future::ready;
6use std::io::Cursor;
7use std::io::Write;
8use std::io::{self};
9
10use futures::AsyncWrite;
11use futures::AsyncWriteExt;
12use vortex_buffer::ByteBufferMut;
13
14use crate::IoBuf;
15
16pub trait VortexWrite: Send {
23 fn write_all<B: IoBuf>(&mut self, buffer: B) -> impl Future<Output = io::Result<B>> + Send;
24 fn flush(&mut self) -> impl Future<Output = io::Result<()>> + Send;
25 fn shutdown(&mut self) -> impl Future<Output = io::Result<()>> + Send;
26}
27
28impl VortexWrite for Vec<u8> {
29 fn write_all<B: IoBuf>(&mut self, buffer: B) -> impl Future<Output = io::Result<B>> + Send {
30 self.extend_from_slice(buffer.as_slice());
31 ready(Ok(buffer))
32 }
33
34 fn flush(&mut self) -> impl Future<Output = io::Result<()>> + Send {
35 ready(Ok(()))
36 }
37
38 fn shutdown(&mut self) -> impl Future<Output = io::Result<()>> + Send {
39 ready(Ok(()))
40 }
41}
42
43impl VortexWrite for ByteBufferMut {
44 fn write_all<B: IoBuf>(&mut self, buffer: B) -> impl Future<Output = io::Result<B>> + Send {
45 self.extend_from_slice(buffer.as_slice());
46 ready(Ok(buffer))
47 }
48
49 fn flush(&mut self) -> impl Future<Output = io::Result<()>> + Send {
50 ready(Ok(()))
51 }
52
53 fn shutdown(&mut self) -> impl Future<Output = io::Result<()>> + Send {
54 ready(Ok(()))
55 }
56}
57
58impl<T: Send> VortexWrite for Cursor<T>
59where
60 Cursor<T>: Write,
61{
62 fn write_all<B: IoBuf>(&mut self, buffer: B) -> impl Future<Output = io::Result<B>> + Send {
63 ready(Write::write_all(self, buffer.as_slice()).map(|_| buffer))
64 }
65
66 fn flush(&mut self) -> impl Future<Output = io::Result<()>> + Send {
67 ready(Write::flush(self))
68 }
69
70 fn shutdown(&mut self) -> impl Future<Output = io::Result<()>> + Send {
71 ready(Write::flush(self))
72 }
73}
74
75impl<W: VortexWrite> VortexWrite for futures::io::Cursor<W> {
76 fn write_all<B: IoBuf>(&mut self, buffer: B) -> impl Future<Output = io::Result<B>> + Send {
77 self.set_position(self.position() + buffer.as_slice().len() as u64);
78 VortexWrite::write_all(self.get_mut(), buffer)
79 }
80
81 fn flush(&mut self) -> impl Future<Output = io::Result<()>> + Send {
82 VortexWrite::flush(self.get_mut())
83 }
84
85 fn shutdown(&mut self) -> impl Future<Output = io::Result<()>> + Send {
86 VortexWrite::shutdown(self.get_mut())
87 }
88}
89
90impl<W: VortexWrite> VortexWrite for &mut W {
91 fn write_all<B: IoBuf>(&mut self, buffer: B) -> impl Future<Output = io::Result<B>> + Send {
92 (*self).write_all(buffer)
93 }
94
95 fn flush(&mut self) -> impl Future<Output = io::Result<()>> + Send {
96 (*self).flush()
97 }
98
99 fn shutdown(&mut self) -> impl Future<Output = io::Result<()>> + Send {
100 (*self).shutdown()
101 }
102}
103
104impl VortexWrite for async_fs::File {
105 async fn write_all<B: IoBuf>(&mut self, buffer: B) -> io::Result<B> {
106 AsyncWriteExt::write_all(self, buffer.as_slice()).await?;
107 Ok(buffer)
108 }
109
110 fn flush(&mut self) -> impl Future<Output = io::Result<()>> + Send {
111 AsyncWriteExt::flush(self)
112 }
113
114 fn shutdown(&mut self) -> impl Future<Output = io::Result<()>> + Send {
115 AsyncWriteExt::close(self)
116 }
117}
118
119pub struct AsyncWriteAdapter<W: AsyncWrite>(pub W);
121impl<W: AsyncWrite + Unpin + Send> VortexWrite for AsyncWriteAdapter<W> {
122 async fn write_all<B: IoBuf>(&mut self, buffer: B) -> io::Result<B> {
123 self.0.write_all(buffer.as_slice()).await?;
124 Ok(buffer)
125 }
126
127 async fn flush(&mut self) -> io::Result<()> {
128 self.0.flush().await
129 }
130
131 async fn shutdown(&mut self) -> io::Result<()> {
132 self.0.close().await
133 }
134}
135
136#[cfg(test)]
137mod tests {
138 use rstest::rstest;
139 use vortex_buffer::ByteBufferMut;
140
141 use super::*;
142
143 #[tokio::test]
146 async fn test_write_futures_are_send() -> io::Result<()> {
147 async fn write_generic<W: VortexWrite>(mut writer: W) -> io::Result<W> {
148 VortexWrite::write_all(&mut writer, vec![1, 2, 3]).await?;
149 VortexWrite::flush(&mut writer).await?;
150 VortexWrite::shutdown(&mut writer).await?;
151 Ok(writer)
152 }
153
154 fn assert_send<F: Future + Send>(future: F) -> F {
155 future
156 }
157
158 assert_eq!(assert_send(write_generic(Vec::new())).await?, vec![1, 2, 3]);
159 Ok(())
160 }
161
162 #[rstest]
163 #[case::single_write(vec![vec![1, 2, 3]], vec![1, 2, 3])]
164 #[case::two_writes(vec![vec![1, 2], vec![3, 4]], vec![1, 2, 3, 4])]
165 #[case::three_writes(vec![vec![1], vec![2], vec![3]], vec![1, 2, 3])]
166 #[case::with_empty(vec![vec![1, 2], vec![], vec![3, 4]], vec![1, 2, 3, 4])]
167 #[tokio::test]
168 async fn test_vec_multiple_writes(#[case] writes: Vec<Vec<u8>>, #[case] expected: Vec<u8>) {
169 let mut writer = Vec::new();
170
171 for data in writes {
172 VortexWrite::write_all(&mut writer, data).await.unwrap();
173 }
174
175 VortexWrite::flush(&mut writer).await.unwrap();
176 VortexWrite::shutdown(&mut writer).await.unwrap();
177 assert_eq!(writer, expected);
178 }
179
180 #[rstest]
181 #[case::single_write(vec![vec![5, 6, 7]], vec![5, 6, 7])]
182 #[case::two_writes(vec![vec![10], vec![20]], vec![10, 20])]
183 #[case::multiple_small(vec![vec![1], vec![2], vec![3], vec![4]], vec![1, 2, 3, 4])]
184 #[tokio::test]
185 async fn test_byte_buffer_mut_operations(
186 #[case] writes: Vec<Vec<u8>>,
187 #[case] expected: Vec<u8>,
188 ) {
189 let mut buffer = ByteBufferMut::with_capacity(0);
190
191 for data in writes {
192 VortexWrite::write_all(&mut buffer, data).await.unwrap();
193 }
194
195 VortexWrite::flush(&mut buffer).await.unwrap();
196 VortexWrite::shutdown(&mut buffer).await.unwrap();
197 assert_eq!(buffer.as_ref(), &expected[..]);
198 }
199
200 #[rstest]
201 #[case::empty(vec![], 0)]
202 #[case::single_byte(vec![42], 1)]
203 #[case::multiple_bytes(vec![1, 2, 3, 4, 5], 5)]
204 #[case::large(vec![0; 1024], 1024)]
205 #[tokio::test]
206 async fn test_various_write_sizes(#[case] data: Vec<u8>, #[case] expected_len: usize) {
207 let mut writer = Vec::new();
208 VortexWrite::write_all(&mut writer, data.clone())
209 .await
210 .unwrap();
211 assert_eq!(writer.len(), expected_len);
212 assert_eq!(writer, data);
213 }
214
215 #[tokio::test]
216 async fn test_cursor_operations() {
217 let mut data = [0u8; 20];
218 {
219 let mut cursor = Cursor::new(&mut data[..]);
220
221 VortexWrite::write_all(&mut cursor, vec![1, 2, 3, 4, 5])
223 .await
224 .unwrap();
225 assert_eq!(cursor.position(), 5);
226
227 VortexWrite::write_all(&mut cursor, vec![6, 7, 8, 9, 10])
229 .await
230 .unwrap();
231 assert_eq!(cursor.position(), 10);
232
233 VortexWrite::flush(&mut cursor).await.unwrap();
235 }
236
237 assert_eq!(&data[..10], &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
239 }
240
241 #[tokio::test]
242 async fn test_futures_cursor() {
243 let mut vec = Vec::new();
244 {
245 let mut cursor = futures::io::Cursor::new(&mut vec);
246
247 VortexWrite::write_all(&mut cursor, vec![10, 20, 30])
249 .await
250 .unwrap();
251 assert_eq!(cursor.position(), 3);
252
253 VortexWrite::write_all(&mut cursor, vec![40, 50])
254 .await
255 .unwrap();
256 assert_eq!(cursor.position(), 5);
257
258 VortexWrite::flush(&mut cursor).await.unwrap();
260 VortexWrite::shutdown(&mut cursor).await.unwrap();
261 }
262
263 assert_eq!(vec, vec![10, 20, 30, 40, 50]);
264 }
265
266 #[tokio::test]
267 async fn test_mutable_reference() {
268 let mut vec = Vec::new();
269 {
270 let mut writer_ref = &mut vec;
271
272 VortexWrite::write_all(&mut writer_ref, vec![100, 101, 102])
274 .await
275 .unwrap();
276
277 VortexWrite::flush(&mut writer_ref).await.unwrap();
278 VortexWrite::shutdown(&mut writer_ref).await.unwrap();
279 }
280
281 assert_eq!(vec, vec![100, 101, 102]);
282 }
283
284 #[tokio::test]
285 async fn test_large_writes() {
286 let mut writer = Vec::new();
287 let large_data = vec![42u8; 100_000];
288
289 VortexWrite::write_all(&mut writer, large_data.clone())
290 .await
291 .unwrap();
292 assert_eq!(writer.len(), 100_000);
293 assert!(writer.iter().all(|&b| b == 42));
294 }
295
296 #[tokio::test]
297 async fn test_empty_writes() {
298 let mut writer = Vec::new();
299 let empty = vec![];
300
301 VortexWrite::write_all(&mut writer, empty.clone())
302 .await
303 .unwrap();
304 assert!(writer.is_empty());
305
306 VortexWrite::write_all(&mut writer, vec![1, 2, 3])
307 .await
308 .unwrap();
309 VortexWrite::write_all(&mut writer, empty).await.unwrap();
310 assert_eq!(writer, vec![1, 2, 3]);
311 }
312
313 #[tokio::test]
314 async fn test_sequential_accumulation() {
315 let mut buffer = ByteBufferMut::with_capacity(0);
316
317 for i in 0u8..5 {
318 VortexWrite::write_all(&mut buffer, vec![i]).await.unwrap();
319 }
320
321 assert_eq!(buffer.len(), 5);
322 assert_eq!(buffer.as_ref(), &[0, 1, 2, 3, 4]);
323 }
324
325 #[rstest]
326 #[case::vec_writer(0)]
327 #[case::byte_buffer(1)]
328 #[tokio::test]
329 async fn test_writer_types(#[case] writer_type: usize) {
330 let data = vec![10, 20, 30];
331
332 match writer_type {
333 0 => {
334 let mut writer = Vec::new();
335 VortexWrite::write_all(&mut writer, data.clone())
336 .await
337 .unwrap();
338 assert_eq!(writer, data);
339 }
340 1 => {
341 let mut writer = ByteBufferMut::with_capacity(0);
342 VortexWrite::write_all(&mut writer, data.clone())
343 .await
344 .unwrap();
345 assert_eq!(writer.as_ref(), &data[..]);
346 }
347 _ => unreachable!(),
348 }
349 }
350}