atlas_rdma/
env.rs

1// SPDX-License-Identifier: AGPL-3.0-only
2//
3// Rail-env resolution helpers. The five RDMA clients share the SHAPE of this
4// logic but not the semantics: two distinct empty-string behaviors exist in
5// the deployed configs and BOTH must be preserved exactly —
6//
7//   * `first_set`      — an exported-but-EMPTY var counts as set (the
8//     `Result::or_else` / `unwrap_or_else` chains: KV / expert / snapshot
9//     single-key reads and the LoRA DEV chain).
10//   * `first_nonempty` — an empty var is SKIPPED (weight tier's `env_str`,
11//     which lets `ATLAS_WEIGHT_RDMA_DEV=""` fall through to the EXPERT name).
12//
13// Each client passes its EXACT key list; the fallback chains are per-tier
14// deployment surface (e.g. LoRA's GID reads ONLY `ATLAS_LORA_RDMA_GID` — no
15// WEIGHT/EXPERT fallback), so no chain is hardcoded here.
16
17/// First key whose var is present in the environment — even if empty.
18pub fn first_set(keys: &[&str], default: &str) -> String {
19    for k in keys {
20        if let Ok(v) = std::env::var(k) {
21            return v;
22        }
23    }
24    default.to_string()
25}
26
27/// First key whose var is present AND non-empty (weight-tier semantics).
28pub fn first_nonempty(keys: &[&str], default: &str) -> String {
29    for k in keys {
30        if let Ok(v) = std::env::var(k)
31            && !v.is_empty()
32        {
33            return v;
34        }
35    }
36    default.to_string()
37}
38
39/// First key whose var is present AND parses as `u32`; otherwise `default`.
40/// (A set-but-unparseable var falls through — the behavior of every existing
41/// per-client `env_u32`, single- and multi-key alike.)
42pub fn first_set_u32(keys: &[&str], default: u32) -> u32 {
43    for k in keys {
44        if let Some(v) = std::env::var(k).ok().and_then(|s| s.parse().ok()) {
45            return v;
46        }
47    }
48    default
49}