knf/env.rs
1//! The process environment, as interpolation wants to see it.
2//!
3//! The only place `std::env` appears in the workspace. Interpolation takes its
4//! environment through a trait so that it stays deterministic and testable
5//! without touching process state; this is the implementation that does not.
6
7use crate::{Env, EnvValue};
8
9use crate::{set, 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(set::json_or_string(raw.clone()));
25 Some(EnvValue { raw, typed })
26 }
27}