#![allow(dead_code)]
use std::io::IsTerminal;
pub struct Terminal;
impl Terminal {
pub fn is_tty() -> bool {
std::io::stdout().is_terminal()
}
pub fn is_stderr_tty() -> bool {
std::io::stderr().is_terminal()
}
pub fn width() -> usize {
Self::size().map(|(w, _)| w).unwrap_or(80)
}
pub fn height() -> usize {
Self::size().map(|(_, h)| h).unwrap_or(24)
}
pub fn size() -> Option<(usize, usize)> {
#[cfg(unix)]
{
Self::unix_terminal_size()
}
#[cfg(windows)]
{
Self::windows_terminal_size()
}
#[cfg(not(any(unix, windows)))]
{
None
}
}
pub fn supports_color() -> bool {
if !Self::is_tty() {
return false;
}
if std::env::var("NO_COLOR").is_ok() {
return false;
}
if let Ok(term) = std::env::var("TERM") {
if term == "dumb" {
return false;
}
}
if std::env::var("CLICOLOR_FORCE").map(|v| v != "0").unwrap_or(false) {
return true;
}
true
}
#[cfg(unix)]
fn unix_terminal_size() -> Option<(usize, usize)> {
use std::os::unix::io::AsRawFd;
let fd = std::io::stdout().as_raw_fd();
let mut winsize: libc::winsize = unsafe { std::mem::zeroed() };
let result = unsafe { libc::ioctl(fd, libc::TIOCGWINSZ, &mut winsize) };
if result == 0 && winsize.ws_col > 0 && winsize.ws_row > 0 {
Some((winsize.ws_col as usize, winsize.ws_row as usize))
} else {
None
}
}
#[cfg(windows)]
fn windows_terminal_size() -> Option<(usize, usize)> {
None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_terminal_width() {
let width = Terminal::width();
assert!(width > 0);
}
#[test]
fn test_terminal_height() {
let height = Terminal::height();
assert!(height > 0);
}
#[test]
fn test_supports_color() {
let _ = Terminal::supports_color();
}
}