Implement and log with panic-free 'write_out!'.

Resolves #2019.
This commit is contained in:
arlecchino 2022-01-17 01:33:59 +01:00 committed by Sergio Benitez
parent 2cbaf05153
commit cc98f98aa7
1 changed files with 25 additions and 15 deletions

View File

@ -35,6 +35,16 @@ define_log_macro!(trace, trace_);
define_log_macro!(launch_info: info, "rocket::launch", $); define_log_macro!(launch_info: info, "rocket::launch", $);
define_log_macro!(launch_info_: info, "rocket::launch_", $); define_log_macro!(launch_info_: info, "rocket::launch_", $);
// `print!` panics when stdout isn't available, but this macro doesn't.
// See SergioBenitez/Rocket#2019 and rust-lang/rust#46016 for more.
macro_rules! write_out {
($($arg:tt)*) => ({
use std::io::{Write, stdout, stderr};
let _ = write!(stdout(), $($arg)*).or_else(|e| write!(stderr(), "{}", e));
})
}
#[derive(Debug)] #[derive(Debug)]
struct RocketLogger; struct RocketLogger;
@ -86,7 +96,7 @@ impl log::Log for RocketLogger {
// In Rocket, we abuse targets with suffix "_" to indicate indentation. // In Rocket, we abuse targets with suffix "_" to indicate indentation.
let indented = record.target().ends_with('_'); let indented = record.target().ends_with('_');
if indented { if indented {
print!(" {} ", Paint::default(">>").bold()); write_out!(" {} ", Paint::default(">>").bold());
} }
// Downgrade a physical launch `warn` to logical `info`. // Downgrade a physical launch `warn` to logical `info`.
@ -96,30 +106,30 @@ impl log::Log for RocketLogger {
match level { match level {
log::Level::Error if !indented => { log::Level::Error if !indented => {
println!("{} {}", write_out!("{} {}\n",
Paint::red("Error:").bold(), Paint::red("Error:").bold(),
Paint::red(record.args()).wrap()) Paint::red(record.args()).wrap());
} }
log::Level::Warn if !indented => { log::Level::Warn if !indented => {
println!("{} {}", write_out!("{} {}\n",
Paint::yellow("Warning:").bold(), Paint::yellow("Warning:").bold(),
Paint::yellow(record.args()).wrap()) Paint::yellow(record.args()).wrap());
} }
log::Level::Info => println!("{}", Paint::blue(record.args()).wrap()), log::Level::Info => write_out!("{}\n", Paint::blue(record.args()).wrap()),
log::Level::Trace => println!("{}", Paint::magenta(record.args()).wrap()), log::Level::Trace => write_out!("{}\n", Paint::magenta(record.args()).wrap()),
log::Level::Warn => println!("{}", Paint::yellow(record.args()).wrap()), log::Level::Warn => write_out!("{}\n", Paint::yellow(record.args()).wrap()),
log::Level::Error => println!("{}", Paint::red(record.args()).wrap()), log::Level::Error => write_out!("{}\n", Paint::red(record.args()).wrap()),
log::Level::Debug => { log::Level::Debug => {
print!("\n{} ", Paint::blue("-->").bold()); write_out!("\n{} ", Paint::blue("-->").bold());
if let Some(file) = record.file() { if let Some(file) = record.file() {
print!("{}", Paint::blue(file)); write_out!("{}", Paint::blue(file));
} }
if let Some(line) = record.line() { if let Some(line) = record.line() {
println!(":{}", Paint::blue(line)); write_out!(":{}\n", Paint::blue(line));
} }
println!("\t{}", record.args()); write_out!("\t{}\n", record.args());
} }
} }
} }