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 | |