From 116b0ac3c99fd317d3800637ca3f88f4d3874c1b Mon Sep 17 00:00:00 2001 From: Jonas Maier Date: Tue, 12 May 2026 21:27:52 +0200 Subject: variable refactor: export builtin --- src/run/var.rs | 52 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-) (limited to 'src/run/var.rs') diff --git a/src/run/var.rs b/src/run/var.rs index 0e64ad7..d3e98f4 100644 --- a/src/run/var.rs +++ b/src/run/var.rs @@ -1,4 +1,7 @@ +use std::borrow::Cow; use std::collections::{HashMap, HashSet}; +use std::sync::LazyLock; +use std::time::Instant; use crate::BString; use crate::bstr; @@ -7,6 +10,7 @@ pub struct Vars { simple: HashMap, magic: HashMap BString>, all: HashSet, + export: HashSet, } impl Vars { @@ -22,7 +26,15 @@ impl Vars { .cloned() .chain(magic.keys().cloned()) .collect(); - Self { simple, magic, all } + let export = std::env::vars_os() + .map(|x| x.0.into_encoded_bytes()) + .collect(); + Self { + simple, + magic, + all, + export, + } } pub fn set(&mut self, var: BString, val: BString) { @@ -30,18 +42,36 @@ impl Vars { self.all.insert(var); } - pub fn lookup(&self, var: &bstr) -> Option { + pub fn lookup<'a>(&'a self, var: &bstr) -> Option> { if let Some(fun) = self.magic.get(var) { - return Some(fun()); + return Some(Cow::Owned(fun())); } if let Some(val) = self.simple.get(var) { - return Some(val.clone()); + return Some(Cow::Borrowed(val)); } None } + pub fn allow_export(&mut self, var: &bstr, allow: bool) { + if allow { + self.export.insert(var.to_vec()); + } else { + self.export.remove(var); + } + } + + pub fn export<'a>(&'a self) -> HashMap<&'a bstr, Cow<'a, bstr>> { + self.export + .iter() + .filter_map(|var| { + let val = self.lookup(var)?; + Some((var.as_ref(), val)) + }) + .collect() + } + pub fn vars(&self) -> &HashSet { &self.all } @@ -62,9 +92,21 @@ impl Default for Vars { 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 _ + b"CWD_PRETTY" => crate::pretty_cwd as _, + b"SECONDS" => seconds_since_startup as _, }; + + // call it once such that lazylock gets initialized + seconds_since_startup(); + Self::new(simple, magic) } } + +static START: LazyLock = LazyLock::new(Instant::now); + +fn seconds_since_startup() -> BString { + format!("{}", START.elapsed().as_secs_f64() as u64).into_bytes() +} -- cgit v1.2.3