#![allow(
clippy::print_stdout,
clippy::print_stderr,
reason = "this module is the binary's terminal output"
)]
use std::fmt::Display;
use std::io::{IsTerminal, Write};
use std::process::ExitCode;
use crate::human::Paint;
pub(crate) fn is_terminal() -> bool {
std::io::stdout().is_terminal()
}
pub(crate) fn paint() -> Paint {
let no_color = std::env::var_os("NO_COLOR").is_some_and(|value| !value.is_empty());
Paint {
colour: is_terminal() && !no_color,
}
}
pub(crate) fn text(text: &str) -> bool {
let mut stdout = std::io::stdout().lock();
stdout
.write_all(text.as_bytes())
.and_then(|()| stdout.flush())
.is_ok()
}
pub(crate) fn line(line: impl Display) -> bool {
text(&format!("{line}\n"))
}
pub(crate) fn redraw(frame: &str) -> bool {
text(&format!("\x1b[H{}\x1b[J", frame.replace('\n', "\x1b[K\n")))
}
pub(crate) fn fail(error: &dyn Display) -> ExitCode {
eprintln!("error: {error}");
ExitCode::FAILURE
}
#[cfg(feature = "tui")]
pub(crate) fn full_screen() -> std::io::Result<ratatui::DefaultTerminal> {
ratatui::try_init()
}
#[cfg(feature = "tui")]
pub(crate) fn restore() -> std::io::Result<()> {
ratatui::try_restore()
}
#[cfg(feature = "tui")]
pub(crate) fn resume() -> std::io::Result<ratatui::DefaultTerminal> {
use ratatui::crossterm::terminal::{EnterAlternateScreen, enable_raw_mode};
enable_raw_mode()?;
ratatui::crossterm::execute!(std::io::stdout(), EnterAlternateScreen)?;
ratatui::Terminal::new(ratatui::backend::CrosstermBackend::new(std::io::stdout()))
}