Skip to content

Commit ffc6646

Browse files
committed
add print macros
Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com>
1 parent 097afd4 commit ffc6646

File tree

4 files changed

+137
-29
lines changed

4 files changed

+137
-29
lines changed

src/io/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ pub use stdout::{stdout, Stdout};
3939
pub use timeout::timeout;
4040
pub use write::Write;
4141

42+
// For use in the print macros.
43+
#[doc(hidden)]
44+
pub use stdio::{_eprint, _print};
45+
4246
pub mod prelude;
4347

4448
pub(crate) mod buf_read;

src/io/stdio.rs

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,20 @@
22
//!
33
//! This module is a port of `libstd/io/stdio.rs`,and contains internal types for `print`/`eprint`.
44
5-
use crate::io::{stderr, stdout, Write};
5+
use crate::prelude::*;
6+
use crate::io::{stderr, stdout};
67
use std::fmt;
78

8-
/// Write `args` `global_s`. `label` identifies the stream in a panic message.
9-
async fn print_to<T>(
10-
args: fmt::Arguments<'_>,
11-
global_s: fn() -> T,
12-
label: &str,
13-
) where
14-
T: Write,
15-
{
16-
if let Err(e) = global_s().write_fmt(args).await {
17-
panic!("failed printing to {}: {}", label, e);
18-
}
19-
}
20-
219
#[doc(hidden)]
2210
pub async fn _print(args: fmt::Arguments<'_>) {
23-
print_to(args, stdout, "stdout");
11+
if let Err(e) = stdout().write_fmt(args).await {
12+
panic!("failed printing to stdout: {}", e);
13+
}
2414
}
2515

2616
#[doc(hidden)]
2717
pub async fn _eprint(args: fmt::Arguments<'_>) {
28-
print_to(args, stderr, "stderr");
18+
if let Err(e) = stderr().write_fmt(args).await {
19+
panic!("failed printing to stderr: {}", e);
20+
}
2921
}

src/io/write/write_fmt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ impl<T: Write + Unpin + ?Sized> Future for WriteFmtFuture<'_, T> {
3636

3737
// Copy the data from the buffer into the writer until it's done.
3838
loop {
39-
if buffer.is_empty() {
39+
if *amt == buffer.len() as u64 {
4040
futures_core::ready!(Pin::new(&mut **writer).poll_flush(cx))?;
4141
return Poll::Ready(Ok(()));
4242
}

src/macros.rs

Lines changed: 124 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,135 @@
2121
/// # Examples
2222
///
2323
/// ```
24-
/// use std::io::{self, Write};
24+
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
25+
/// #
26+
/// use async_std::prelude::*;
27+
/// use async_std::io;
28+
/// use async_std::print;
2529
///
26-
/// print!("this ");
27-
/// print!("will ");
28-
/// print!("be ");
29-
/// print!("on ");
30-
/// print!("the ");
31-
/// print!("same ");
32-
/// print!("line ");
30+
/// print!("this ").await;
31+
/// print!("will ").await;
32+
/// print!("be ").await;
33+
/// print!("on ").await;
34+
/// print!("the ").await;
35+
/// print!("same ").await;
36+
/// print!("line ").await;
3337
///
34-
/// io::stdout().flush().unwrap();
38+
/// io::stdout().flush().await.unwrap();
3539
///
36-
/// print!("this string has a newline, why not choose println! instead?\n");
40+
/// print!("this string has a newline, why not choose println! instead?\n").await;
3741
///
38-
/// io::stdout().flush().unwrap();
42+
/// io::stdout().flush().await.unwrap();
43+
/// #
44+
/// # Ok(()) }) }
3945
/// ```
4046
#[macro_export]
4147
macro_rules! print {
42-
($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)));
48+
($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)))
49+
}
50+
51+
/// Prints to the standard output, with a newline.
52+
///
53+
/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
54+
/// (no additional CARRIAGE RETURN (`\r`/`U+000D`)).
55+
///
56+
/// Use the [`format!`] syntax to write data to the standard output.
57+
/// See [`std::fmt`] for more information.
58+
///
59+
/// Use `println!` only for the primary output of your program. Use
60+
/// [`eprintln!`] instead to print error and progress messages.
61+
///
62+
/// [`format!`]: macro.format.html
63+
/// [`std::fmt`]: https://doc.rust-lang.org/std/fmt/index.html
64+
/// [`eprintln!`]: macro.eprintln.html
65+
/// # Panics
66+
///
67+
/// Panics if writing to `io::stdout` fails.
68+
///
69+
/// # Examples
70+
///
71+
/// ```
72+
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
73+
/// #
74+
/// use async_std::println;
75+
///
76+
/// println!().await; // prints just a newline
77+
/// println!("hello there!").await;
78+
/// println!("format {} arguments", "some").await;
79+
/// #
80+
/// # Ok(()) }) }
81+
/// ```
82+
#[macro_export]
83+
macro_rules! println {
84+
() => ($crate::print!("\n"));
85+
($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)))
86+
}
87+
88+
/// Prints to the standard error.
89+
///
90+
/// Equivalent to the [`print!`] macro, except that output goes to
91+
/// [`io::stderr`] instead of `io::stdout`. See [`print!`] for
92+
/// example usage.
93+
///
94+
/// Use `eprint!` only for error and progress messages. Use `print!`
95+
/// instead for the primary output of your program.
96+
///
97+
/// [`io::stderr`]: io/struct.Stderr.html
98+
/// [`print!`]: macro.print.html
99+
///
100+
/// # Panics
101+
///
102+
/// Panics if writing to `io::stderr` fails.
103+
///
104+
/// # Examples
105+
///
106+
/// ```
107+
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
108+
/// #
109+
/// use async_std::eprint;
110+
///
111+
/// eprint!("Error: Could not complete task").await;
112+
/// #
113+
/// # Ok(()) }) }
114+
/// ```
115+
#[macro_export]
116+
macro_rules! eprint {
117+
($($arg:tt)*) => ($crate::io::_eprint(format_args!($($arg)*)))
118+
}
119+
120+
/// Prints to the standard error, with a newline.
121+
///
122+
/// Equivalent to the [`println!`] macro, except that output goes to
123+
/// [`io::stderr`] instead of `io::stdout`. See [`println!`] for
124+
/// example usage.
125+
///
126+
/// Use `eprintln!` only for error and progress messages. Use `println!`
127+
/// instead for the primary output of your program.
128+
///
129+
/// [`io::stderr`]: io/struct.Stderr.html
130+
/// [`println!`]: macro.println.html
131+
///
132+
/// # Panics
133+
///
134+
/// Panics if writing to `io::stderr` fails.
135+
///
136+
/// # Examples
137+
///
138+
/// ```
139+
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
140+
/// #
141+
/// use async_std::eprintln;
142+
///
143+
/// eprintln!("Error: Could not complete task").await;
144+
/// #
145+
/// # Ok(()) }) }
146+
/// ```
147+
#[macro_export]
148+
macro_rules! eprintln {
149+
() => (async { $crate::eprint!("\n").await; });
150+
($($arg:tt)*) => (
151+
async {
152+
$crate::io::_eprint(format_args!($($arg)*)).await;
153+
}
154+
);
43155
}

0 commit comments

Comments
 (0)