use std::io;
use std::sync::atomic::{AtomicBool, Ordering};
use tracing_subscriber::fmt::MakeWriter;
static TUI_QUIET: AtomicBool = AtomicBool::new(false);
pub fn set_tui_quiet(quiet: bool) {
TUI_QUIET.store(quiet, Ordering::Relaxed);
}
pub fn is_tui_quiet() -> bool {
TUI_QUIET.load(Ordering::Relaxed)
}
pub struct TuiQuietGuard;
impl Drop for TuiQuietGuard {
fn drop(&mut self) {
set_tui_quiet(false);
}
}
pub fn suppress_tracing_for_tui() -> TuiQuietGuard {
set_tui_quiet(true);
TuiQuietGuard
}
#[derive(Debug)]
pub struct StderrOrNull;
impl io::Write for StderrOrNull {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
if TUI_QUIET.load(Ordering::Relaxed) {
return Ok(buf.len());
}
let mut handle = std::io::stderr().lock();
handle.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
if TUI_QUIET.load(Ordering::Relaxed) {
return Ok(());
}
std::io::stderr().flush()
}
}
#[derive(Clone, Debug)]
pub struct StderrOrNullMaker;
impl<'a> MakeWriter<'a> for StderrOrNullMaker {
type Writer = StderrOrNull;
fn make_writer(&'a self) -> Self::Writer {
StderrOrNull
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::io::Write;
#[test]
fn stderr_or_null_drops_bytes_when_quiet() {
set_tui_quiet(true);
let mut w = StderrOrNull;
let n = w.write(b"hello").unwrap();
assert_eq!(n, 5);
w.flush().unwrap();
set_tui_quiet(false);
}
#[test]
fn guard_restores_quiet_state_on_drop() {
assert!(!is_tui_quiet());
{
let _g = suppress_tracing_for_tui();
assert!(is_tui_quiet());
}
assert!(!is_tui_quiet());
}
#[test]
fn guard_restores_even_if_another_guard_already_dropped() {
let _outer = suppress_tracing_for_tui();
assert!(is_tui_quiet());
{
let _inner = suppress_tracing_for_tui();
assert!(is_tui_quiet());
}
assert!(
!is_tui_quiet(),
"inner guard's drop already cleared the flag (documented)"
);
}
}