use core::fmt;
use std::{error::Error, ffi::OsString};
#[cfg(feature = "parking_lot")]
use parking_lot::Mutex;
#[cfg(not(feature = "parking_lot"))]
use std::sync::Mutex;
pub(crate) type EnvMap = std::collections::BTreeMap<OsString, OsString>;
pub(crate) static ENV_MAP: Mutex<EnvMap> = Mutex::new(EnvMap::new());
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum VarError {
NotPresent,
NotUnicode(OsString),
}
impl fmt::Display for VarError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
VarError::NotPresent => write!(f, "environment variable not found"),
VarError::NotUnicode(ref s) => {
write!(f, "environment variable was not valid unicode: {s:?}")
}
}
}
}
impl Error for VarError {
fn description(&self) -> &str {
match *self {
VarError::NotPresent => "environment variable not found",
VarError::NotUnicode(..) => "environment variable was not valid unicode",
}
}
}
#[derive(Debug)]
pub struct VarsOs {
pub(crate) inner: std::collections::btree_map::IntoIter<std::ffi::OsString, std::ffi::OsString>,
}
impl Iterator for VarsOs {
type Item = (OsString, OsString);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(k, v)| (k.clone(), v.clone()))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
#[derive(Debug)]
pub struct Vars {
pub(crate) inner: VarsOs,
}
impl Iterator for Vars {
type Item = (String, String);
fn next(&mut self) -> Option<Self::Item> {
self.inner
.next()
.map(|(k, v)| (k.into_string().unwrap(), v.into_string().unwrap()))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}