mirror of
https://github.com/async-rs/async-std.git
synced 2025-05-24 16:01:29 +00:00
324 lines
10 KiB
Rust
324 lines
10 KiB
Rust
mod flush;
|
|
mod write;
|
|
mod write_all;
|
|
mod write_fmt;
|
|
mod write_vectored;
|
|
|
|
use flush::FlushFuture;
|
|
use write::WriteFuture;
|
|
use write_all::WriteAllFuture;
|
|
use write_fmt::WriteFmtFuture;
|
|
use write_vectored::WriteVectoredFuture;
|
|
|
|
use crate::io::{self, IoSlice};
|
|
|
|
extension_trait! {
|
|
use std::pin::Pin;
|
|
use std::ops::{Deref, DerefMut};
|
|
|
|
use crate::task::{Context, Poll};
|
|
|
|
#[doc = r#"
|
|
Allows writing to a byte stream.
|
|
|
|
This trait is a re-export of [`futures::io::AsyncWrite`] and is an async version of
|
|
[`std::io::Write`].
|
|
|
|
Methods other than [`poll_write`], [`poll_write_vectored`], [`poll_flush`], and
|
|
[`poll_close`] do not really exist in the trait itself, but they become available when
|
|
[`WriteExt`] from the [prelude] is imported:
|
|
|
|
```
|
|
# #[allow(unused_imports)]
|
|
use async_std::prelude::*;
|
|
```
|
|
|
|
[`std::io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
|
|
[`futures::io::AsyncWrite`]:
|
|
https://docs.rs/futures/0.3/futures/io/trait.AsyncWrite.html
|
|
[`poll_write`]: #tymethod.poll_write
|
|
[`poll_write_vectored`]: #method.poll_write_vectored
|
|
[`poll_flush`]: #tymethod.poll_flush
|
|
[`poll_close`]: #tymethod.poll_close
|
|
[`WriteExt`]: ../io/prelude/trait.WriteExt.html
|
|
[prelude]: ../prelude/index.html
|
|
"#]
|
|
pub trait Write {
|
|
#[doc = r#"
|
|
Attempt to write bytes from `buf` into the object.
|
|
"#]
|
|
fn poll_write(
|
|
self: Pin<&mut Self>,
|
|
cx: &mut Context<'_>,
|
|
buf: &[u8],
|
|
) -> Poll<io::Result<usize>>;
|
|
|
|
#[doc = r#"
|
|
Attempt to write bytes from `bufs` into the object using vectored IO operations.
|
|
"#]
|
|
fn poll_write_vectored(
|
|
self: Pin<&mut Self>,
|
|
cx: &mut Context<'_>,
|
|
bufs: &[IoSlice<'_>]
|
|
) -> Poll<io::Result<usize>> {
|
|
unreachable!("this impl only appears in the rendered docs")
|
|
}
|
|
|
|
#[doc = r#"
|
|
Attempt to flush the object, ensuring that any buffered data reach
|
|
their destination.
|
|
"#]
|
|
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>>;
|
|
|
|
#[doc = r#"
|
|
Attempt to close the object.
|
|
"#]
|
|
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>>;
|
|
}
|
|
|
|
#[doc = r#"
|
|
Extension methods for [`Write`].
|
|
|
|
[`Write`]: ../trait.Write.html
|
|
"#]
|
|
pub trait WriteExt: futures_io::AsyncWrite {
|
|
#[doc = r#"
|
|
Writes some bytes into the byte stream.
|
|
|
|
Returns the number of bytes written from the start of the buffer.
|
|
|
|
If the return value is `Ok(n)` then it must be guaranteed that
|
|
`0 <= n <= buf.len()`. A return value of `0` typically means that the underlying
|
|
object is no longer able to accept bytes and will likely not be able to in the
|
|
future as well, or that the buffer provided is empty.
|
|
|
|
# Examples
|
|
|
|
```no_run
|
|
# fn main() -> std::io::Result<()> { async_std::task::block_on(async {
|
|
#
|
|
use async_std::fs::File;
|
|
use async_std::prelude::*;
|
|
|
|
let mut file = File::create("a.txt").await?;
|
|
|
|
let n = file.write(b"hello world").await?;
|
|
#
|
|
# Ok(()) }) }
|
|
```
|
|
"#]
|
|
fn write<'a>(
|
|
&'a mut self,
|
|
buf: &'a [u8],
|
|
) -> impl Future<Output = io::Result<usize>> + 'a [WriteFuture<'a, Self>]
|
|
where
|
|
Self: Unpin,
|
|
{
|
|
WriteFuture { writer: self, buf }
|
|
}
|
|
|
|
#[doc = r#"
|
|
Flushes the stream to ensure that all buffered contents reach their destination.
|
|
|
|
# Examples
|
|
|
|
```no_run
|
|
# fn main() -> std::io::Result<()> { async_std::task::block_on(async {
|
|
#
|
|
use async_std::fs::File;
|
|
use async_std::prelude::*;
|
|
|
|
let mut file = File::create("a.txt").await?;
|
|
|
|
file.write_all(b"hello world").await?;
|
|
file.flush().await?;
|
|
#
|
|
# Ok(()) }) }
|
|
```
|
|
"#]
|
|
fn flush(&mut self) -> impl Future<Output = io::Result<()>> + '_ [FlushFuture<'_, Self>]
|
|
where
|
|
Self: Unpin,
|
|
{
|
|
FlushFuture { writer: self }
|
|
}
|
|
|
|
#[doc = r#"
|
|
Like [`write`], except that it writes from a slice of buffers.
|
|
|
|
Data is copied from each buffer in order, with the final buffer read from possibly
|
|
being only partially consumed. This method must behave as a call to [`write`] with
|
|
the buffers concatenated would.
|
|
|
|
The default implementation calls [`write`] with either the first nonempty buffer
|
|
provided, or an empty one if none exists.
|
|
|
|
[`write`]: #tymethod.write
|
|
"#]
|
|
fn write_vectored<'a>(
|
|
&'a mut self,
|
|
bufs: &'a [IoSlice<'a>],
|
|
) -> impl Future<Output = io::Result<usize>> + 'a [WriteVectoredFuture<'a, Self>]
|
|
where
|
|
Self: Unpin,
|
|
{
|
|
WriteVectoredFuture { writer: self, bufs }
|
|
}
|
|
|
|
#[doc = r#"
|
|
Writes an entire buffer into the byte stream.
|
|
|
|
This method will continuously call [`write`] until there is no more data to be
|
|
written or an error is returned. This method will not return until the entire
|
|
buffer has been successfully written or such an error occurs.
|
|
|
|
[`write`]: #tymethod.write
|
|
|
|
# Examples
|
|
|
|
```no_run
|
|
# fn main() -> std::io::Result<()> { async_std::task::block_on(async {
|
|
#
|
|
use async_std::fs::File;
|
|
use async_std::prelude::*;
|
|
|
|
let mut file = File::create("a.txt").await?;
|
|
|
|
file.write_all(b"hello world").await?;
|
|
#
|
|
# Ok(()) }) }
|
|
```
|
|
|
|
[`write`]: #tymethod.write
|
|
"#]
|
|
fn write_all<'a>(
|
|
&'a mut self,
|
|
buf: &'a [u8],
|
|
) -> impl Future<Output = io::Result<()>> + 'a [WriteAllFuture<'a, Self>]
|
|
where
|
|
Self: Unpin,
|
|
{
|
|
WriteAllFuture { writer: self, buf }
|
|
}
|
|
|
|
#[doc = r#"
|
|
Writes a formatted string into this writer, returning any error encountered.
|
|
|
|
This method will continuously call [`write`] until there is no more data to be
|
|
written or an error is returned. This future will not resolve until the entire
|
|
buffer has been successfully written or such an error occurs.
|
|
|
|
[`write`]: #tymethod.write
|
|
|
|
# Examples
|
|
|
|
```no_run
|
|
# fn main() -> std::io::Result<()> { async_std::task::block_on(async {
|
|
#
|
|
use async_std::io::prelude::*;
|
|
use async_std::fs::File;
|
|
|
|
let mut buffer = File::create("foo.txt").await?;
|
|
|
|
// this call
|
|
write!(buffer, "{:.*}", 2, 1.234567).await?;
|
|
// turns into this:
|
|
buffer.write_fmt(format_args!("{:.*}", 2, 1.234567)).await?;
|
|
#
|
|
# Ok(()) }) }
|
|
```
|
|
"#]
|
|
fn write_fmt<'a>(
|
|
&'a mut self,
|
|
fmt: std::fmt::Arguments<'_>,
|
|
) -> impl Future<Output = io::Result<()>> + 'a [WriteFmtFuture<'a, Self>]
|
|
where
|
|
Self: Unpin,
|
|
{
|
|
// In order to not have to implement an async version of `fmt` including private types
|
|
// and all, we convert `Arguments` to a `Result<Vec<u8>>` and pass that to the Future.
|
|
// Doing an owned conversion saves us from juggling references.
|
|
let mut string = String::new();
|
|
let res = std::fmt::write(&mut string, fmt)
|
|
.map(|_| string.into_bytes())
|
|
.map_err(|_| io::Error::new(io::ErrorKind::Other, "formatter error"));
|
|
WriteFmtFuture { writer: self, res: Some(res), buffer: None, amt: 0 }
|
|
}
|
|
}
|
|
|
|
impl<T: Write + Unpin + ?Sized> Write for Box<T> {
|
|
fn poll_write(
|
|
self: Pin<&mut Self>,
|
|
cx: &mut Context<'_>,
|
|
buf: &[u8],
|
|
) -> Poll<io::Result<usize>> {
|
|
unreachable!("this impl only appears in the rendered docs")
|
|
}
|
|
|
|
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
|
unreachable!("this impl only appears in the rendered docs")
|
|
}
|
|
|
|
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
|
unreachable!("this impl only appears in the rendered docs")
|
|
}
|
|
}
|
|
|
|
impl<T: Write + Unpin + ?Sized> Write for &mut T {
|
|
fn poll_write(
|
|
self: Pin<&mut Self>,
|
|
cx: &mut Context<'_>,
|
|
buf: &[u8],
|
|
) -> Poll<io::Result<usize>> {
|
|
unreachable!("this impl only appears in the rendered docs")
|
|
}
|
|
|
|
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
|
unreachable!("this impl only appears in the rendered docs")
|
|
}
|
|
|
|
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
|
unreachable!("this impl only appears in the rendered docs")
|
|
}
|
|
}
|
|
|
|
impl<P> Write for Pin<P>
|
|
where
|
|
P: DerefMut + Unpin,
|
|
<P as Deref>::Target: Write,
|
|
{
|
|
fn poll_write(
|
|
self: Pin<&mut Self>,
|
|
cx: &mut Context<'_>,
|
|
buf: &[u8],
|
|
) -> Poll<io::Result<usize>> {
|
|
unreachable!("this impl only appears in the rendered docs")
|
|
}
|
|
|
|
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
|
unreachable!("this impl only appears in the rendered docs")
|
|
}
|
|
|
|
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
|
unreachable!("this impl only appears in the rendered docs")
|
|
}
|
|
}
|
|
|
|
impl Write for Vec<u8> {
|
|
fn poll_write(
|
|
self: Pin<&mut Self>,
|
|
cx: &mut Context<'_>,
|
|
buf: &[u8],
|
|
) -> Poll<io::Result<usize>> {
|
|
unreachable!("this impl only appears in the rendered docs")
|
|
}
|
|
|
|
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
|
unreachable!("this impl only appears in the rendered docs")
|
|
}
|
|
|
|
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
|
unreachable!("this impl only appears in the rendered docs")
|
|
}
|
|
}
|
|
}
|