knf/interp.rs
1//! The process environment, as `knf-interp` wants to see it.
2//!
3//! The only place `std::env` appears. `knf-interp` takes its environment through
4//! a trait so that it stays deterministic and testable without touching process
5//! state; this is the implementation that does not.
6
7use knf_interp::{Env, EnvValue};
8
9use crate::value;
10
11/// Reads `${env:NAME}` from the real environment.
12pub struct ProcessEnv;
13
14impl Env for ProcessEnv {
15 fn lookup(&self, name: &str) -> Option<EnvValue> {
16 // `var` also fails on a non-UTF-8 value, which reads here as unset. That
17 // is the only outcome available: bytes that are not UTF-8 cannot be
18 // spliced into a JSON or TOML document either way.
19 let raw = std::env::var(name).ok()?;
20 // The same typing rule as `--set`'s RHS, from the same function — which
21 // is the whole consistency argument for typing environment values at
22 // all. Going through JSON also means this can never fabricate a
23 // `Datetime`: JSON has no such type.
24 let typed = value::from_json(knf_dotted::json_or_string(raw.clone()));
25 Some(EnvValue { raw, typed })
26 }
27}