irid-std 0.3.1

A replacement for std when running without a filesystem on the irid kernel
Documentation
use core::io::ErrorKind;

use alloc::{borrow::ToOwned, boxed::Box, collections::btree_map::BTreeMap, string::{String, ToString}, vec::Vec};

use crate::{ffi::{OsStr, OsString}, io::Error, path::{Path, PathBuf}, sync::{Mutex, MutexGuard}};

static ARGS: Mutex<Vec<Box<str>>> = Mutex::new(Vec::new());
static VARS: Mutex<BTreeMap<Box<str>, Box<str>>> = Mutex::new(BTreeMap::new());

pub fn args() -> impl Iterator<Item = String> {
    ARGS.lock().expect("args lock poisoned").iter().map(|x| x.to_string()).collect::<Vec<_>>().into_iter()
}

pub fn args_os() -> impl Iterator<Item = OsString> {
    args().map(OsString::from)
}

pub fn current_dir() -> Result<PathBuf, Error> {
    Ok(PathBuf::from(OsString::from(var("PWD").unwrap_or("/".to_owned()))))
}

pub fn set_current_dir(path: impl AsRef<Path>) -> Result<(), Error> {
    unsafe { set_var("PWD", path.as_ref()) };

    Ok(())
}

pub fn current_exe() -> Result<PathBuf, Error> {
    Ok(Path::new(&args().next().ok_or(Error::from(ErrorKind::NotFound))?).to_owned())
}

pub fn home_dir() -> Option<PathBuf> {
    Some(PathBuf::from(OsString::from(var("HOME")?)))
}

pub fn temp_dir() -> PathBuf {
    var("TMPDIR").map(|x| PathBuf::from(OsString::from(x))).unwrap_or_else(|| Path::new("/tmp").to_owned())
}

pub fn var(name: impl AsRef<OsStr>) -> Option<String> {
    VARS.lock().expect("vars lock poisoned").get(name.as_ref().as_str())
        .map(|x| x.to_string())
}

pub fn var_os(name: impl AsRef<OsStr>) -> Option<OsString> {
    var(name).map(OsString::from)
}

pub fn vars() -> impl Iterator<Item = (String, String)> {
    VARS.lock().expect("vars lock poisoned").iter().map(|(k, v)| (k.to_string(), v.to_string())).collect::<Vec<_>>().into_iter()
}

pub fn vars_os() -> impl Iterator<Item = (OsString, OsString)> {
    vars().map(|(a, b)| (OsString::from(a), OsString::from(b)))
}

pub unsafe fn set_var(key: impl AsRef<OsStr>, value: impl AsRef<OsStr>) {
    VARS.lock().expect("vars lock poisoned").insert(key.as_ref().as_str().to_owned().into_boxed_str(), value.as_ref().as_str().to_owned().into_boxed_str());
}

pub(crate) fn arg_lock() -> MutexGuard<'static, Vec<Box<str>>> {
    ARGS.lock().expect("failed to lock args")
}

pub(crate) fn var_lock() -> MutexGuard<'static, BTreeMap<Box<str>, Box<str>>> {
    VARS.lock().expect("failed to lock vars")
}