1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//! `safe_print!` and `safe_println!` macros
//!
//! REF: <https://github.com/rust-lang/rust/blob/master/compiler/rustc_driver_impl/src/print.rs>
use std::fmt;
use std::io::{self, Write as _};
#[macro_export]
macro_rules! safe_print {
($($arg:tt)*) => {{
#[allow(clippy::unwrap_used)]
$crate::print::print(std::format_args!($($arg)*)) .unwrap();
}};
}
#[macro_export]
macro_rules! safe_println {
($($arg:tt)*) => {
safe_print!("{}\n", std::format_args!($($arg)*))
};
}
pub fn print(args: fmt::Arguments<'_>) -> Result<(), io::Error> {
if let Err(err) = io::stdout().write_fmt(args) {
if err.kind() == io::ErrorKind::BrokenPipe {
// This is a common error when the output is piped to a command that exits
// before this process finishes writing. We can ignore it.
Ok(())
} else if err.kind() == io::ErrorKind::WriteZero {
// This error indicates that the write buffer is full and we can't write to it.
// We can ignore it as well.
Ok(())
} else {
// For any other error, we should panic.
Err(io::Error::new(
err.kind(),
format!("Error writing to stdout: {err}"),
))
}
} else {
// Flush the output to ensure it is written immediately.
io::stdout().flush()?;
Ok(())
}
}