aboutsummaryrefslogtreecommitdiffstats
path: root/src/run/var.rs
diff options
context:
space:
mode:
authorJonas Maier <jonas@x77.dev>2026-05-12 21:06:03 +0200
committerJonas Maier <jonas@x77.dev>2026-05-12 21:06:03 +0200
commit0e5d95663aaac8b7368c82290476694b561536d3 (patch)
tree3d1118430d6b05daf2cc8b81c3dd570feb26452e /src/run/var.rs
parent90b34c8cc26d9adf2a1e8ae5169fb6dd0edb01c8 (diff)
downloadpish-0e5d95663aaac8b7368c82290476694b561536d3.tar.gz
variable refactor: completion also for magic vars
Diffstat (limited to 'src/run/var.rs')
-rw-r--r--src/run/var.rs70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/run/var.rs b/src/run/var.rs
new file mode 100644
index 0000000..0e64ad7
--- /dev/null
+++ b/src/run/var.rs
@@ -0,0 +1,70 @@
+use std::collections::{HashMap, HashSet};
+
+use crate::BString;
+use crate::bstr;
+
+pub struct Vars {
+ simple: HashMap<BString, BString>,
+ magic: HashMap<BString, fn() -> BString>,
+ all: HashSet<BString>,
+}
+
+impl Vars {
+ fn new(
+ mut simple: HashMap<BString, BString>,
+ magic: HashMap<BString, fn() -> 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<BString> {
+ 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<BString> {
+ &self.all
+ }
+}
+
+macro_rules! map {
+ ($($key:expr => $val:expr),* $(,)?) => {{
+ let mut map = HashMap::<BString, _, _>::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)
+ }
+}