Skip to content

Add print, println, eprint, eprintln #319

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ pub use stdout::{stdout, Stdout};
pub use timeout::timeout;
pub use write::Write;

// For use in the print macros.
#[doc(hidden)]
pub use stdio::{_eprint, _print};

pub mod prelude;

pub(crate) mod buf_read;
Expand All @@ -55,5 +59,6 @@ mod repeat;
mod sink;
mod stderr;
mod stdin;
mod stdio;
mod stdout;
mod timeout;
21 changes: 21 additions & 0 deletions src/io/stdio.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//! Internal types for stdio.
//!
//! This module is a port of `libstd/io/stdio.rs`,and contains internal types for `print`/`eprint`.

use crate::io::{stderr, stdout};
use crate::prelude::*;
use std::fmt;

#[doc(hidden)]
pub async fn _print(args: fmt::Arguments<'_>) {
if let Err(e) = stdout().write_fmt(args).await {
panic!("failed printing to stdout: {}", e);
}
}

#[doc(hidden)]
pub async fn _eprint(args: fmt::Arguments<'_>) {
if let Err(e) = stderr().write_fmt(args).await {
panic!("failed printing to stderr: {}", e);
}
}
2 changes: 1 addition & 1 deletion src/io/write/write_fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl<T: Write + Unpin + ?Sized> Future for WriteFmtFuture<'_, T> {

// Copy the data from the buffer into the writer until it's done.
loop {
if buffer.is_empty() {
if *amt == buffer.len() as u64 {
futures_core::ready!(Pin::new(&mut **writer).poll_flush(cx))?;
return Poll::Ready(Ok(()));
}
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ cfg_if! {
}
}

mod macros;
pub(crate) mod utils;

#[doc(inline)]
Expand Down
155 changes: 155 additions & 0 deletions src/macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/// Prints to the standard output.
///
/// Equivalent to the [`println!`] macro except that a newline is not printed at
/// the end of the message.
///
/// Note that stdout is frequently line-buffered by default so it may be
/// necessary to use [`io::stdout().flush()`][flush] to ensure the output is emitted
/// immediately.
///
/// Use `print!` only for the primary output of your program. Use
/// [`eprint!`] instead to print error and progress messages.
///
/// [`println!`]: macro.println.html
/// [flush]: io/trait.Write.html#tymethod.flush
/// [`eprint!`]: macro.eprint.html
///
/// # Panics
///
/// Panics if writing to `io::stdout()` fails.
///
/// # Examples
///
/// ```
/// # async_std::task::block_on(async {
/// #
/// use async_std::prelude::*;
/// use async_std::io;
/// use async_std::print;
///
/// print!("this ").await;
/// print!("will ").await;
/// print!("be ").await;
/// print!("on ").await;
/// print!("the ").await;
/// print!("same ").await;
/// print!("line ").await;
///
/// io::stdout().flush().await.unwrap();
///
/// print!("this string has a newline, why not choose println! instead?\n").await;
///
/// io::stdout().flush().await.unwrap();
/// #
/// # })
/// ```
#[macro_export]
macro_rules! print {
($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)))
}

/// Prints to the standard output, with a newline.
///
/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
/// (no additional CARRIAGE RETURN (`\r`/`U+000D`)).
///
/// Use the [`format!`] syntax to write data to the standard output.
/// See [`std::fmt`] for more information.
///
/// Use `println!` only for the primary output of your program. Use
/// [`eprintln!`] instead to print error and progress messages.
///
/// [`format!`]: macro.format.html
/// [`std::fmt`]: https://doc.rust-lang.org/std/fmt/index.html
/// [`eprintln!`]: macro.eprintln.html
/// # Panics
///
/// Panics if writing to `io::stdout` fails.
///
/// # Examples
///
/// ```
/// # async_std::task::block_on(async {
/// #
/// use async_std::println;
///
/// println!().await; // prints just a newline
/// println!("hello there!").await;
/// println!("format {} arguments", "some").await;
/// #
/// # })
/// ```
#[macro_export]
macro_rules! println {
() => ($crate::print!("\n"));
($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)))
}

/// Prints to the standard error.
///
/// Equivalent to the [`print!`] macro, except that output goes to
/// [`io::stderr`] instead of `io::stdout`. See [`print!`] for
/// example usage.
///
/// Use `eprint!` only for error and progress messages. Use `print!`
/// instead for the primary output of your program.
///
/// [`io::stderr`]: io/struct.Stderr.html
/// [`print!`]: macro.print.html
///
/// # Panics
///
/// Panics if writing to `io::stderr` fails.
///
/// # Examples
///
/// ```
/// # async_std::task::block_on(async {
/// #
/// use async_std::eprint;
///
/// eprint!("Error: Could not complete task").await;
/// #
/// # })
/// ```
#[macro_export]
macro_rules! eprint {
($($arg:tt)*) => ($crate::io::_eprint(format_args!($($arg)*)))
}

/// Prints to the standard error, with a newline.
///
/// Equivalent to the [`println!`] macro, except that output goes to
/// [`io::stderr`] instead of `io::stdout`. See [`println!`] for
/// example usage.
///
/// Use `eprintln!` only for error and progress messages. Use `println!`
/// instead for the primary output of your program.
///
/// [`io::stderr`]: io/struct.Stderr.html
/// [`println!`]: macro.println.html
///
/// # Panics
///
/// Panics if writing to `io::stderr` fails.
///
/// # Examples
///
/// ```
/// # async_std::task::block_on(async {
/// #
/// use async_std::eprintln;
///
/// eprintln!("Error: Could not complete task").await;
/// #
/// # })
/// ```
#[macro_export]
macro_rules! eprintln {
() => (async { $crate::eprint!("\n").await; });
($($arg:tt)*) => (
async {
$crate::io::_eprint(format_args!($($arg)*)).await;
}
);
}