Skip to content

Commit b9bddbb

Browse files
authored
Merge pull request #319 from async-rs/print
Add print, println, eprint, eprintln
2 parents 33da049 + fef2e32 commit b9bddbb

File tree

5 files changed

+183
-1
lines changed

5 files changed

+183
-1
lines changed

src/io/mod.rs

+5
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;
@@ -55,5 +59,6 @@ mod repeat;
5559
mod sink;
5660
mod stderr;
5761
mod stdin;
62+
mod stdio;
5863
mod stdout;
5964
mod timeout;

src/io/stdio.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//! Internal types for stdio.
2+
//!
3+
//! This module is a port of `libstd/io/stdio.rs`,and contains internal types for `print`/`eprint`.
4+
5+
use crate::io::{stderr, stdout};
6+
use crate::prelude::*;
7+
use std::fmt;
8+
9+
#[doc(hidden)]
10+
pub async fn _print(args: fmt::Arguments<'_>) {
11+
if let Err(e) = stdout().write_fmt(args).await {
12+
panic!("failed printing to stdout: {}", e);
13+
}
14+
}
15+
16+
#[doc(hidden)]
17+
pub async fn _eprint(args: fmt::Arguments<'_>) {
18+
if let Err(e) = stderr().write_fmt(args).await {
19+
panic!("failed printing to stderr: {}", e);
20+
}
21+
}

src/io/write/write_fmt.rs

+1-1
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/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ cfg_if! {
7676
}
7777
}
7878

79+
mod macros;
7980
pub(crate) mod utils;
8081

8182
#[doc(inline)]

src/macros.rs

+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/// Prints to the standard output.
2+
///
3+
/// Equivalent to the [`println!`] macro except that a newline is not printed at
4+
/// the end of the message.
5+
///
6+
/// Note that stdout is frequently line-buffered by default so it may be
7+
/// necessary to use [`io::stdout().flush()`][flush] to ensure the output is emitted
8+
/// immediately.
9+
///
10+
/// Use `print!` only for the primary output of your program. Use
11+
/// [`eprint!`] instead to print error and progress messages.
12+
///
13+
/// [`println!`]: macro.println.html
14+
/// [flush]: io/trait.Write.html#tymethod.flush
15+
/// [`eprint!`]: macro.eprint.html
16+
///
17+
/// # Panics
18+
///
19+
/// Panics if writing to `io::stdout()` fails.
20+
///
21+
/// # Examples
22+
///
23+
/// ```
24+
/// # async_std::task::block_on(async {
25+
/// #
26+
/// use async_std::prelude::*;
27+
/// use async_std::io;
28+
/// use async_std::print;
29+
///
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;
37+
///
38+
/// io::stdout().flush().await.unwrap();
39+
///
40+
/// print!("this string has a newline, why not choose println! instead?\n").await;
41+
///
42+
/// io::stdout().flush().await.unwrap();
43+
/// #
44+
/// # })
45+
/// ```
46+
#[macro_export]
47+
macro_rules! print {
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+
/// # 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+
/// # })
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+
/// # async_std::task::block_on(async {
108+
/// #
109+
/// use async_std::eprint;
110+
///
111+
/// eprint!("Error: Could not complete task").await;
112+
/// #
113+
/// # })
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+
/// # async_std::task::block_on(async {
140+
/// #
141+
/// use async_std::eprintln;
142+
///
143+
/// eprintln!("Error: Could not complete task").await;
144+
/// #
145+
/// # })
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+
);
155+
}

0 commit comments

Comments
 (0)