use std::fmt;
use std::io::Write;
use std::sync::OnceLock;
use libc;
pub const NBSP: char = '\u{00A0}';
pub fn wwriteln(stream: &mut dyn Write, msg: fmt::Arguments) {
let m = format!("{}", msg);
for l in textwrap::wrap(&m, options()) {
if let Err(e) = writeln!(stream, "{}", l) {
let mut exit_code = 1;
#[cfg(unix)]
if e.kind() == std::io::ErrorKind::BrokenPipe {
exit_code = 128 + libc::SIGPIPE;
} else {
eprintln!("Error: {}", e);
}
std::process::exit(exit_code);
}
}
}
pub fn iwwriteln(stream: &mut dyn Write,
initial_indent: &str,
subsequent_indent: &str,
msg: fmt::Arguments) {
let m = format!("{}", msg);
for l in textwrap::wrap(&m,
options()
.initial_indent(initial_indent)
.subsequent_indent(subsequent_indent)) {
if let Err(e) = writeln!(stream, "{}", l) {
let mut exit_code = 1;
#[cfg(unix)]
if e.kind() == std::io::ErrorKind::BrokenPipe {
exit_code = 128 + libc::SIGPIPE;
} else {
eprintln!("Error: {}", e);
}
std::process::exit(exit_code);
}
}
}
fn options() -> textwrap::Options<'static> {
static OPTIONS: OnceLock<textwrap::Options> = OnceLock::new();
OPTIONS.get_or_init(|| {
textwrap::Options::new(stderr_terminal_width())
.word_separator(textwrap::WordSeparator::AsciiSpace)
}).clone()
}
pub fn stderr_terminal_width() -> usize {
platform! {
unix => {
use std::os::fd::AsRawFd;
#[allow(deprecated)]
unsafe {
terminal_size::terminal_size_using_fd(std::io::stderr().as_raw_fd())
}
},
windows => {
terminal_size::terminal_size()
},
}
.map(|(w, _h)| w.0)
.map(Into::into)
.unwrap_or(usize::MAX)
}