pub mod input;
pub mod output;
use is_terminal::IsTerminal;
use std::ffi::{c_void, OsStr};
use std::iter::once;
use std::os::windows::io::AsRawHandle;
use std::os::windows::prelude::{AsHandle, FromRawHandle, OsStrExt};
use std::ptr::null_mut;
use std::{fs, io};
use windows_sys::Win32::Storage::FileSystem::{
CreateFileW, FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_SHARE_WRITE, OPEN_EXISTING,
};
use windows_sys::Win32::System::Console::*;
pub fn get_console_mode(handle: impl AsHandle) -> io::Result<u32> {
let handle = handle.as_handle().as_raw_handle() as isize;
let mut console_mode: u32 = 0;
super::result(
"getting console mode",
0,
unsafe { GetConsoleMode(handle, &mut console_mode) } as isize,
)?;
Ok(console_mode)
}
pub fn set_console_mode(handle: impl AsHandle, console_mode: u32) -> io::Result<()> {
let handle = handle.as_handle().as_raw_handle() as isize;
super::result(
"setting console mode",
0,
unsafe { SetConsoleMode(handle, console_mode) } as isize,
)?;
Ok(())
}
pub fn open_console(output: bool) -> io::Result<fs::File> {
let name = if output { "CONOUT$" } else { "CONIN$" };
let console_out_name: Vec<u16> = OsStr::new(name).encode_wide().chain(once(0)).collect();
let console_handle = super::result("opening console", -1, unsafe {
CreateFileW(
console_out_name.as_ptr(),
FILE_GENERIC_READ | FILE_GENERIC_WRITE,
FILE_SHARE_WRITE,
null_mut(),
OPEN_EXISTING,
0,
0,
)
})?;
Ok(unsafe { fs::File::from_raw_handle(console_handle as *mut c_void) })
}
pub fn is_tty<FD>(fd: FD) -> Option<FD>
where
FD: AsHandle,
{
if fd.is_terminal() {
Some(fd)
} else {
None
}
}