From 04479b13c3a80895fc642079dfd465a640be58a9 Mon Sep 17 00:00:00 2001 From: Yoshua Wuyts Date: Sun, 13 Oct 2019 12:13:29 +0200 Subject: [PATCH] add io::stdio Signed-off-by: Yoshua Wuyts --- src/io/mod.rs | 1 + src/io/stdio.rs | 29 +++++++++++++++++++++++++++++ src/lib.rs | 1 + src/macros.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+) create mode 100644 src/io/stdio.rs create mode 100644 src/macros.rs diff --git a/src/io/mod.rs b/src/io/mod.rs index 7a94285..eef6d73 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -55,5 +55,6 @@ mod repeat; mod sink; mod stderr; mod stdin; +mod stdio; mod stdout; mod timeout; diff --git a/src/io/stdio.rs b/src/io/stdio.rs new file mode 100644 index 0000000..2a4a366 --- /dev/null +++ b/src/io/stdio.rs @@ -0,0 +1,29 @@ +//! 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, Write}; +use std::fmt; + +/// Write `args` `global_s`. `label` identifies the stream in a panic message. +async fn print_to( + args: fmt::Arguments<'_>, + global_s: fn() -> T, + label: &str, +) where + T: Write, +{ + if let Err(e) = global_s().write_fmt(args).await { + panic!("failed printing to {}: {}", label, e); + } +} + +#[doc(hidden)] +pub async fn _print(args: fmt::Arguments<'_>) { + print_to(args, stdout, "stdout"); +} + +#[doc(hidden)] +pub async fn _eprint(args: fmt::Arguments<'_>) { + print_to(args, stderr, "stderr"); +} diff --git a/src/lib.rs b/src/lib.rs index f1ed43e..f69d1f8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,6 +76,7 @@ cfg_if! { } } +mod macros; pub(crate) mod utils; #[doc(inline)] diff --git a/src/macros.rs b/src/macros.rs new file mode 100644 index 0000000..80d784d --- /dev/null +++ b/src/macros.rs @@ -0,0 +1,43 @@ +/// 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 +/// +/// ``` +/// use std::io::{self, Write}; +/// +/// print!("this "); +/// print!("will "); +/// print!("be "); +/// print!("on "); +/// print!("the "); +/// print!("same "); +/// print!("line "); +/// +/// io::stdout().flush().unwrap(); +/// +/// print!("this string has a newline, why not choose println! instead?\n"); +/// +/// io::stdout().flush().unwrap(); +/// ``` +#[macro_export] +macro_rules! print { + ($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*))); +}