use std::collections::{HashMap, HashSet}; use crate::BString; use crate::bstr; pub struct Vars { simple: HashMap, magic: HashMap BString>, all: HashSet, } impl Vars { fn new( mut simple: HashMap, magic: HashMap BString>, ) -> Self { for (var, val) in std::env::vars_os() { simple.insert(var.into_encoded_bytes(), val.into_encoded_bytes()); } let all = simple .keys() .cloned() .chain(magic.keys().cloned()) .collect(); Self { simple, magic, all } } pub fn set(&mut self, var: BString, val: BString) { self.simple.insert(var.clone(), val); self.all.insert(var); } pub fn lookup(&self, var: &bstr) -> Option { if let Some(fun) = self.magic.get(var) { return Some(fun()); } if let Some(val) = self.simple.get(var) { return Some(val.clone()); } None } pub fn vars(&self) -> &HashSet { &self.all } } macro_rules! map { ($($key:expr => $val:expr),* $(,)?) => {{ let mut map = HashMap::::new(); $(map.insert($key.into(), $val);)* map }}; } impl Default for Vars { fn default() -> Self { let simple = map! { b"PISH_VERSION" => crate::consts::PISH_VERSION.as_bytes().to_vec(), b"PISH_COMMIT" => crate::consts::PISH_COMMIT.as_bytes().to_vec(), b"PISH_DIRTY" => vec![crate::consts::PISH_DIRTY as u8 + b'0'], }; let magic = map! { b"CWD_PRETTY" => crate::pretty_cwd as _ }; Self::new(simple, magic) } }