use std::path::{Path, PathBuf};
use crate::error::{Error, Result};
pub fn check_free_space(path: &Path, required: u64) -> Result<()> {
let check = if path.exists() {
path.to_path_buf()
} else {
let mut p = path.to_path_buf();
while !p.exists() {
if !p.pop() {
return Ok(()); }
}
p
};
match fs2::available_space(&check) {
Ok(available) if available < required => Err(Error::NoSpace {
path: path.to_path_buf(),
required: Some(required),
available: Some(available),
}),
_ => Ok(()),
}
}
pub fn open_url(url: &str) {
let _ = open::that(url);
}
pub fn os_name() -> &'static str {
if cfg!(target_os = "macos") {
"mac"
} else if cfg!(target_os = "windows") {
"windows"
} else {
"linux"
}
}
pub fn arch_name() -> &'static str {
if cfg!(target_arch = "aarch64") {
if cfg!(target_os = "linux") {
"aarch64"
} else {
"arm64"
}
} else {
"x86_64"
}
}
pub fn tag_os() -> String {
let arch_prefix = if cfg!(target_arch = "aarch64") {
"arm"
} else {
"x64"
};
let os_suffix = if cfg!(target_os = "macos") {
"mac"
} else if cfg!(target_os = "windows") {
"win"
} else {
"linux"
};
format!("{arch_prefix}{os_suffix}")
}
pub fn executable_path() -> PathBuf {
std::env::current_exe().unwrap_or_else(|_| PathBuf::from("hcli"))
}
pub fn is_binary() -> bool {
std::env::var("CARGO").is_err() && cfg!(not(debug_assertions))
}
#[allow(dead_code)]
pub fn read_text_file(path: &Path) -> Result<String> {
let bytes = std::fs::read(path)?;
if bytes.starts_with(&[0xFF, 0xFE]) {
let (cow, _enc, _had_errors) = encoding_rs::UTF_16LE.decode(&bytes[2..]);
return Ok(cow.into_owned());
}
match std::str::from_utf8(&bytes) {
Ok(s) => Ok(s.to_owned()),
Err(_) => {
let (cow, _enc, _had_errors) = encoding_rs::WINDOWS_1252.decode(&bytes);
Ok(cow.into_owned())
}
}
}