| 1 | mod flush; |
| 2 | mod write; |
| 3 | mod write_all; |
| 4 | mod write_fmt; |
| 5 | mod write_vectored; |
| 6 | |
| 7 | use flush::FlushFuture; |
| 8 | use write::WriteFuture; |
| 9 | use write_all::WriteAllFuture; |
| 10 | use write_fmt::WriteFmtFuture; |
| 11 | use write_vectored::WriteVectoredFuture; |
| 12 | |
| 13 | use crate::io::{self, IoSlice}; |
| 14 | |
| 15 | pub use futures_io::AsyncWrite as Write; |
| 16 | |
| 17 | #[doc = r#" |
| 18 | Extension methods for [`Write`]. |
| 19 | |
| 20 | [`Write`]: ../trait.Write.html |
| 21 | "# ] |
| 22 | pub trait WriteExt: Write { |
| 23 | #[doc = r#" |
| 24 | Writes some bytes into the byte stream. |
| 25 | |
| 26 | Returns the number of bytes written from the start of the buffer. |
| 27 | |
| 28 | If the return value is `Ok(n)` then it must be guaranteed that |
| 29 | `0 <= n <= buf.len()`. A return value of `0` typically means that the underlying |
| 30 | object is no longer able to accept bytes and will likely not be able to in the |
| 31 | future as well, or that the buffer provided is empty. |
| 32 | |
| 33 | # Examples |
| 34 | |
| 35 | ```no_run |
| 36 | # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
| 37 | # |
| 38 | use async_std::fs::File; |
| 39 | use async_std::prelude::*; |
| 40 | |
| 41 | let mut file = File::create("a.txt" ).await?; |
| 42 | |
| 43 | let n = file.write(b"hello world" ).await?; |
| 44 | # |
| 45 | # Ok(()) }) } |
| 46 | ``` |
| 47 | "# ] |
| 48 | fn write<'a>( |
| 49 | &'a mut self, |
| 50 | buf: &'a [u8], |
| 51 | ) -> WriteFuture<'a, Self> |
| 52 | where |
| 53 | Self: Unpin, |
| 54 | { |
| 55 | WriteFuture { writer: self, buf } |
| 56 | } |
| 57 | |
| 58 | #[doc = r#" |
| 59 | Flushes the stream to ensure that all buffered contents reach their destination. |
| 60 | |
| 61 | # Examples |
| 62 | |
| 63 | ```no_run |
| 64 | # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
| 65 | # |
| 66 | use async_std::fs::File; |
| 67 | use async_std::prelude::*; |
| 68 | |
| 69 | let mut file = File::create("a.txt" ).await?; |
| 70 | |
| 71 | file.write_all(b"hello world" ).await?; |
| 72 | file.flush().await?; |
| 73 | # |
| 74 | # Ok(()) }) } |
| 75 | ``` |
| 76 | "# ] |
| 77 | fn flush(&mut self) -> FlushFuture<'_, Self> |
| 78 | where |
| 79 | Self: Unpin, |
| 80 | { |
| 81 | FlushFuture { writer: self } |
| 82 | } |
| 83 | |
| 84 | #[doc = r#" |
| 85 | Like [`write`], except that it writes from a slice of buffers. |
| 86 | |
| 87 | Data is copied from each buffer in order, with the final buffer read from possibly |
| 88 | being only partially consumed. This method must behave as a call to [`write`] with |
| 89 | the buffers concatenated would. |
| 90 | |
| 91 | The default implementation calls [`write`] with either the first nonempty buffer |
| 92 | provided, or an empty one if none exists. |
| 93 | |
| 94 | [`write`]: #tymethod.write |
| 95 | "# ] |
| 96 | fn write_vectored<'a>( |
| 97 | &'a mut self, |
| 98 | bufs: &'a [IoSlice<'a>], |
| 99 | ) -> WriteVectoredFuture<'a, Self> |
| 100 | where |
| 101 | Self: Unpin, |
| 102 | { |
| 103 | WriteVectoredFuture { writer: self, bufs } |
| 104 | } |
| 105 | |
| 106 | #[doc = r#" |
| 107 | Writes an entire buffer into the byte stream. |
| 108 | |
| 109 | This method will continuously call [`write`] until there is no more data to be |
| 110 | written or an error is returned. This method will not return until the entire |
| 111 | buffer has been successfully written or such an error occurs. |
| 112 | |
| 113 | [`write`]: #tymethod.write |
| 114 | |
| 115 | # Examples |
| 116 | |
| 117 | ```no_run |
| 118 | # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
| 119 | # |
| 120 | use async_std::fs::File; |
| 121 | use async_std::prelude::*; |
| 122 | |
| 123 | let mut file = File::create("a.txt" ).await?; |
| 124 | |
| 125 | file.write_all(b"hello world" ).await?; |
| 126 | # |
| 127 | # Ok(()) }) } |
| 128 | ``` |
| 129 | |
| 130 | [`write`]: #tymethod.write |
| 131 | "# ] |
| 132 | fn write_all<'a>( |
| 133 | &'a mut self, |
| 134 | buf: &'a [u8], |
| 135 | ) -> WriteAllFuture<'a, Self> |
| 136 | where |
| 137 | Self: Unpin, |
| 138 | { |
| 139 | WriteAllFuture { writer: self, buf } |
| 140 | } |
| 141 | |
| 142 | #[doc = r#" |
| 143 | Writes a formatted string into this writer, returning any error encountered. |
| 144 | |
| 145 | This method will continuously call [`write`] until there is no more data to be |
| 146 | written or an error is returned. This future will not resolve until the entire |
| 147 | buffer has been successfully written or such an error occurs. |
| 148 | |
| 149 | [`write`]: #tymethod.write |
| 150 | |
| 151 | # Examples |
| 152 | |
| 153 | ```no_run |
| 154 | # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
| 155 | # |
| 156 | use async_std::io::prelude::*; |
| 157 | use async_std::fs::File; |
| 158 | |
| 159 | let mut buffer = File::create("foo.txt" ).await?; |
| 160 | |
| 161 | // this call |
| 162 | write!(buffer, "{:.*}" , 2, 1.234567).await?; |
| 163 | // turns into this: |
| 164 | buffer.write_fmt(format_args!("{:.*}" , 2, 1.234567)).await?; |
| 165 | # |
| 166 | # Ok(()) }) } |
| 167 | ``` |
| 168 | "# ] |
| 169 | fn write_fmt<'a>( |
| 170 | &'a mut self, |
| 171 | fmt: std::fmt::Arguments<'_>, |
| 172 | ) -> WriteFmtFuture<'a, Self> |
| 173 | where |
| 174 | Self: Unpin, |
| 175 | { |
| 176 | // In order to not have to implement an async version of `fmt` including private types |
| 177 | // and all, we convert `Arguments` to a `Result<Vec<u8>>` and pass that to the Future. |
| 178 | // Doing an owned conversion saves us from juggling references. |
| 179 | let mut string = String::new(); |
| 180 | let res = std::fmt::write(&mut string, fmt) |
| 181 | .map(|_| string.into_bytes()) |
| 182 | .map_err(|_| io::Error::new(io::ErrorKind::Other, "formatter error" )); |
| 183 | WriteFmtFuture { writer: self, res: Some(res), buffer: None, amt: 0 } |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | impl<T: Write + ?Sized> WriteExt for T {} |
| 188 | |