1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//! IO related utilities functions for ease of use.

mod take;
pub use take::Take;

mod null;
pub use null::{null, Null};

mod repeat;
pub use repeat::{repeat, Repeat};

mod internal;
pub(crate) use internal::*;

use crate::{buffer::Buffer, AsyncRead, AsyncWrite, IoResult};

/// Asynchronously copies the entire contents of a reader into a writer.
///
/// This function returns a future that will continuously read data from
/// `reader` and then write it into `writer` in a streaming fashion until
/// `reader` returns EOF or fails.
///
/// On success, the total number of bytes that were copied from `reader` to
/// `writer` is returned.
///
/// This is an asynchronous version of [`std::io::copy`][std].
///
/// A heap-allocated copy buffer with 8 KB is created to take data from the
/// reader to the writer.
pub async fn copy<'a, R: AsyncRead, W: AsyncWrite>(
    reader: &'a mut R,
    writer: &'a mut W,
) -> IoResult<usize> {
    let mut buf = Buffer::with_capacity(DEFAULT_BUF_SIZE);
    let mut total = 0;

    loop {
        let read = buf.with(|w| reader.read(w)).await?;

        // When EOF is reached, we are terminating, so flush before that
        if read == 0 || buf.need_flush() {
            let written = buf.flush_to(writer).await?;
            total += written;
        }

        if read == 0 {
            writer.flush().await?;
            break;
        }
    }

    Ok(total)
}