#[derive(Clone, Copy, PartialEq)]
pub enum Stream {
Stdin,
Stdout,
Stderr,
}
#[cfg(target_family = "windows")]
pub use crate::tty::windows::isatty;
#[cfg(target_family = "unix")]
pub use crate::tty::unix::isatty;
#[cfg(target_family = "windows")]
mod windows {
use crate::tty::Stream;
use crate::win32::{GetFileType, GetStdHandle};
use crate::win32::{
INVALID_HANDLE_VALUE, STD_ERROR_HANDLE, STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
};
use std::os::windows::raw::HANDLE;
#[allow(clippy::let_and_return)]
pub fn isatty(stream: Stream) -> bool {
let handle = match stream {
Stream::Stdin => match get_handle(STD_INPUT_HANDLE) {
Ok(h) => h,
Err(_) => return false,
},
Stream::Stdout => match get_handle(STD_OUTPUT_HANDLE) {
Ok(h) => h,
Err(_) => return false,
},
Stream::Stderr => match get_handle(STD_ERROR_HANDLE) {
Ok(h) => h,
Err(_) => return false,
},
};
let is_atty = unsafe {
GetFileType(handle) == crate::win32::FILE_TYPE_CHAR
};
is_atty
}
fn get_handle(input_handle: u32) -> Result<HANDLE, ()> {
let handle = unsafe { GetStdHandle(input_handle) };
if handle == INVALID_HANDLE_VALUE {
return Err(());
}
Ok(handle)
}
}
#[cfg(target_family = "unix")]
mod unix {
use crate::tty::Stream;
use libc::{STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO};
#[allow(clippy::let_and_return)]
pub fn isatty(stream: Stream) -> bool {
let is_atty = unsafe {
match stream {
Stream::Stdin => libc::isatty(STDIN_FILENO) == 1,
Stream::Stdout => libc::isatty(STDOUT_FILENO) == 1,
Stream::Stderr => libc::isatty(STDERR_FILENO) == 1,
}
};
is_atty
}
}