| Crates.io | futures-copy |
| lib.rs | futures-copy |
| version | 0.2.2 |
| created_at | 2025-10-30 14:40:05.529034+00 |
| updated_at | 2026-01-13 17:08:08.457396+00 |
| description | Copy data between AsyncRead and AsyncWrite, with bidirectional and flushing support |
| homepage | https://gitlab.torproject.org/tpo/core/arti/-/wikis/home |
| repository | https://gitlab.torproject.org/tpo/core/arti.git/ |
| max_upload_size | |
| id | 1908336 |
| size | 81,261 |
Copy data from an AsyncRead to an AsyncWrite,
or between a pair of AsyncRead + AsyncWrite streams.
(If you're using tokio only, you probably don't need this;
you can probably use one of the tokio::io::copy functions instead.)
copysThis crate works with the AsyncRead and AsyncWrite traits
from the [futures] crate.
Unlike futures::io::copy and some of the copy methods in tokio,
the code in this crate flushes the writer
whenever the reader returns Pending,
and so is suitable for use in more cases:
this behavior ensures that data does not wait forever on writers with internal buffering.
futures-copy ensures that the writer is flushed
whenever the reader has returned Pending.
futures-copy doesn't require reader and writer types to be Unpin,
and allows readers and writers to be given either by value or by
mutable reference.
futures-copy lets you control the way in which an EOF received
on one stream is copied to the other (e.g., via AsyncWriteExt::close,
TcpStream::shutdown, or some other means.)
The io::Error that's returned by the functions in futures-copy
is not exactly the same io::Error that caused the copy operation to fail.
Instead, it wraps the source error in an Arc,
We do this because, in Rust,
[std::io::Error] doesn't implement [Clone].
Although futures-copy returns the amount of data transferred on success,
it does not report this information on error.
If an error occurs while reading data,
futures_copy tries to ensure that the writer is flushed
before it returns that error.
This may delay receipt of the error message.
# use futures::io::{AsyncRead, AsyncWrite};
# use std::io;
use futures_copy::{copy_bidirectional, eof};
# async fn x(stream_a: impl AsyncRead+AsyncWrite,
# stream_b: impl AsyncRead+AsyncWrite) -> io::Result<()> {
// Copy data between stream_a and stream_b, in both directions,
// flushing as appropriate.
// As soon as we reach EOF on either stream, close the other.
copy_bidirectional(
stream_a, stream_b,
eof::Close, eof::Close
).await?;
# Ok(())
# }
The API is loosely based on the API of tokio's io::copy* functions,
(copy_buf, copy, and copy_bidirectional),
ported for use outside tokio.
The implementation strategy is loosely based on the implementation strategy of futures's
io::copy methods (copy and copy_buf).
It should be mostly usable as a drop-in replacement for those functions.
License: MIT OR Apache-2.0