use std::{
env::{self, home_dir},
io,
path::PathBuf,
};
use libc::{STDOUT_FILENO, TIOCGWINSZ, c_ushort, ioctl};
pub fn m2_cache_dir() -> Option<PathBuf> {
env::var_os("XDG_CACHE_HOME")
.map(Into::into)
.or_else(|| Some(home_dir()?.join(".cache")))
.map(|path| path.join("m2"))
}
pub fn terminal_size() -> io::Result<(u16, u16)> {
trait IsMinusOne {
fn is_minus_one(&self) -> bool;
}
macro_rules! impl_is_minus_one {
($($t:ident)*) => ($(impl IsMinusOne for $t {
fn is_minus_one(&self) -> bool {
*self == -1
}
})*)
}
impl_is_minus_one! { i8 i16 i32 i64 isize }
fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> {
if t.is_minus_one() {
Err(io::Error::last_os_error())
} else {
Ok(t)
}
}
#[repr(C)]
struct TermSize {
row: c_ushort,
col: c_ushort,
x: c_ushort,
y: c_ushort,
}
unsafe {
let mut size: TermSize = std::mem::zeroed();
cvt(ioctl(STDOUT_FILENO, TIOCGWINSZ, &mut size as *mut _))?;
Ok((size.col, size.row))
}
}