Skip to content

Commit 58c3a06

Browse files
committed
init write_fmt
Signed-off-by: Yoshua Wuyts <[email protected]>
1 parent 30b5ca5 commit 58c3a06

File tree

5 files changed

+93
-2
lines changed

5 files changed

+93
-2
lines changed

src/io/fmt/mod.rs

Whitespace-only changes.

src/io/fmt/write.rs

Whitespace-only changes.

src/io/write/mod.rs

+45-2
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,26 @@
11
mod flush;
22
mod write;
33
mod write_all;
4+
mod write_fmt;
45
mod write_vectored;
56

67
use flush::FlushFuture;
78
use write::WriteFuture;
89
use write_all::WriteAllFuture;
10+
use write_fmt::WriteFmtFuture;
911
use write_vectored::WriteVectoredFuture;
1012

1113
use cfg_if::cfg_if;
1214

1315
use crate::io::IoSlice;
1416
use crate::utils::extension_trait;
1517

18+
use crate::io;
19+
1620
cfg_if! {
1721
if #[cfg(feature = "docs")] {
1822
use std::pin::Pin;
1923
use std::ops::{Deref, DerefMut};
20-
21-
use crate::io;
2224
use crate::task::{Context, Poll};
2325
}
2426
}
@@ -197,6 +199,47 @@ extension_trait! {
197199
{
198200
WriteAllFuture { writer: self, buf }
199201
}
202+
203+
#[doc = r#"
204+
Writes a formatted string into this writer, returning any error encountered.
205+
206+
This method will continuously call [`write`] until there is no more data to be
207+
written or an error is returned. This method will not return until the entire
208+
buffer has been successfully written or such an error occurs.
209+
210+
[`write`]: #tymethod.write
211+
212+
# Examples
213+
214+
```no_run
215+
# fn main() -> std::io::Result<()> { async_std::task::block_on(async {
216+
#
217+
use async_std::io::prelude::*;
218+
use async_std::fs::File;
219+
220+
let mut buffer = File::create("foo.txt").await?;
221+
222+
// this call
223+
write!(buffer, "{:.*}", 2, 1.234567).await?;
224+
// turns into this:
225+
buffer.write_fmt(format_args!("{:.*}", 2, 1.234567)).await?;
226+
#
227+
# Ok(()) }) }
228+
```
229+
"#]
230+
fn write_fmt<'a>(
231+
&'a mut self,
232+
fmt: std::fmt::Arguments<'_>,
233+
) -> impl Future<Output = io::Result<()>> + 'a [WriteFmtFuture<'a, Self>]
234+
where
235+
Self: Unpin,
236+
{
237+
let mut string = String::new();
238+
let res = std::fmt::write(&mut string, fmt)
239+
.map(|_| string.into_bytes())
240+
.map_err(|_| io::Error::new(io::ErrorKind::Other, "formatter error"));
241+
WriteFmtFuture { writer: self, res: Some(res), buffer: None, amt: 0 }
242+
}
200243
}
201244

202245
impl<T: Write + Unpin + ?Sized> Write for Box<T> {

src/io/write/write_fmt.rs

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
use std::pin::Pin;
2+
3+
use crate::future::Future;
4+
use crate::io::{self, Write};
5+
use crate::task::{Context, Poll};
6+
7+
#[doc(hidden)]
8+
#[allow(missing_debug_implementations)]
9+
pub struct WriteFmtFuture<'a, T: Unpin + ?Sized> {
10+
pub(crate) writer: &'a mut T,
11+
pub(crate) res: Option<io::Result<Vec<u8>>>,
12+
pub(crate) buffer: Option<Vec<u8>>,
13+
pub(crate) amt: u64,
14+
}
15+
16+
impl<T: Write + Unpin + ?Sized> Future for WriteFmtFuture<'_, T> {
17+
type Output = io::Result<()>;
18+
19+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
20+
21+
// Process the interal Result the first time we run.
22+
if self.buffer.is_none() {
23+
match self.res.take().unwrap() {
24+
Err(err) => return Poll::Ready(Err(err)),
25+
Ok(buffer) => self.buffer = Some(buffer),
26+
};
27+
}
28+
29+
let Self { writer, amt, buffer, .. } = &mut *self;
30+
let mut buffer = buffer.as_mut().unwrap();
31+
32+
loop {
33+
if buffer.is_empty() {
34+
futures_core::ready!(Pin::new(&mut **writer).poll_flush(cx))?;
35+
return Poll::Ready(Ok(()));
36+
}
37+
38+
let i = futures_core::ready!(Pin::new(&mut **writer).poll_write(cx, &mut buffer))?;
39+
if i == 0 {
40+
return Poll::Ready(Err(io::ErrorKind::WriteZero.into()));
41+
}
42+
*amt += i as u64;
43+
}
44+
}
45+
}

src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,6 @@ cfg_if! {
7777
}
7878

7979
pub(crate) mod utils;
80+
81+
#[doc(inline)]
82+
pub use std::{write, writeln};

0 commit comments

Comments
 (0)