aboutsummaryrefslogtreecommitdiffstats
path: root/src/run/var.rs
diff options
context:
space:
mode:
authorJonas Maier <jonas@x77.dev>2026-05-12 21:27:52 +0200
committerJonas Maier <jonas@x77.dev>2026-05-12 21:27:52 +0200
commit116b0ac3c99fd317d3800637ca3f88f4d3874c1b (patch)
tree29982dbac0ed23275c960ff1be24600e7468cbf6 /src/run/var.rs
parent0e5d95663aaac8b7368c82290476694b561536d3 (diff)
downloadpish-116b0ac3c99fd317d3800637ca3f88f4d3874c1b.tar.gz
variable refactor: export builtin
Diffstat (limited to 'src/run/var.rs')
-rw-r--r--src/run/var.rs52
1 files changed, 47 insertions, 5 deletions
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<BString, BString>,
magic: HashMap<BString, fn() -> BString>,
all: HashSet<BString>,
+ export: HashSet<BString>,
}
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<BString> {
+ pub fn lookup<'a>(&'a self, var: &bstr) -> Option<Cow<'a, bstr>> {
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<BString> {
&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<Instant> = LazyLock::new(Instant::now);
+
+fn seconds_since_startup() -> BString {
+ format!("{}", START.elapsed().as_secs_f64() as u64).into_bytes()
+}