From e1a7a746014942ea0f8cb45486134cbe6b7dc374 Mon Sep 17 00:00:00 2001 From: Chris Beck Date: Sun, 7 Jul 2024 09:33:02 -0600 Subject: [PATCH] feat: Add an `env_with_source` function to `Arg` This is intended to resolve #4607, and also my earlier request https://github.com/clap-rs/clap/issues/5104 which was closed in favor of #4607 This is obviously not as powerful as the plugin system envisioned here https://github.com/clap-rs/clap/issues/4607#issuecomment-1485850523 but it is simple and might be a useful stopgap until such time as the plugin system exists. Fixes #4607 --- clap_builder/src/builder/arg.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/clap_builder/src/builder/arg.rs b/clap_builder/src/builder/arg.rs index d0929e515d3..b9572b2975b 100644 --- a/clap_builder/src/builder/arg.rs +++ b/clap_builder/src/builder/arg.rs @@ -2035,9 +2035,23 @@ impl Arg { #[cfg(feature = "env")] #[inline] #[must_use] - pub fn env(mut self, name: impl IntoResettable) -> Self { + pub fn env(self, name: impl IntoResettable) -> Self { + self.env_with_source(name, std::env::var_os) + } + + /// Read from `name` environment variable when argument is not present, using `env_source` function instead of `std::env::var_os` to access the environment. + /// + /// This is intended to be used instead of `.env` for tests which you may want to isolate from the actual environment, or for wasm build targets and such. + #[cfg(feature = "env")] + #[inline] + #[must_use] + pub fn env_with_source( + mut self, + name: impl IntoResettable, + env_source: impl FnOnce(&OsStr) -> Option, + ) -> Self { if let Some(name) = name.into_resettable().into_option() { - let value = env::var_os(&name); + let value = env_source(&name); self.env = Some((name, value)); } else { self.env = None;