use std::io;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct TerminalSize {
width: u16,
height: u16,
}
impl TerminalSize {
#[inline]
pub fn get() -> io::Result<Self> {
#[cfg(windows)]
{
use windows_sys::Win32::System::Console::{
GetConsoleScreenBufferInfo, GetStdHandle, CONSOLE_SCREEN_BUFFER_INFO, STD_OUTPUT_HANDLE,
};
#[allow(unsafe_code)]
unsafe {
let handle = GetStdHandle(STD_OUTPUT_HANDLE);
let mut info: CONSOLE_SCREEN_BUFFER_INFO = std::mem::zeroed();
if GetConsoleScreenBufferInfo(handle, &mut info) == 0 {
return Err(io::Error::last_os_error());
}
Ok(Self {
width: (info.srWindow.Right - info.srWindow.Left + 1) as u16,
height: (info.srWindow.Bottom - info.srWindow.Top + 1) as u16,
})
}
}
#[cfg(unix)]
{
use libc::{ioctl, winsize, STDOUT_FILENO, TIOCGWINSZ};
use std::mem::MaybeUninit;
let mut w = MaybeUninit::<winsize>::uninit();
#[allow(unsafe_code)]
let res = unsafe { ioctl(STDOUT_FILENO, TIOCGWINSZ, w.as_mut_ptr()) };
if res == 0 {
#[allow(unsafe_code)]
let size = unsafe { w.assume_init() };
Ok(Self {
width: size.ws_col,
height: size.ws_row,
})
} else {
Err(io::Error::last_os_error())
}
}
}
#[must_use]
#[inline]
pub const fn width(&self) -> u16 {
self.width
}
#[must_use]
#[inline]
pub const fn height(&self) -> u16 {
self.height
}
}