use std::collections::HashSet;
use std::sync::Mutex;
use once_cell::sync::Lazy;
static WARNED: Lazy<Mutex<HashSet<&'static str>>> = Lazy::new(|| Mutex::new(HashSet::new()));
pub fn read_env_with_legacy(new_name: &'static str, legacy_name: &'static str) -> Option<String> {
if let Ok(v) = std::env::var(new_name) {
if !v.is_empty() {
return Some(v);
}
}
match std::env::var(legacy_name) {
Ok(v) if !v.is_empty() => {
warn_legacy_once(legacy_name, new_name);
Some(v)
}
_ => None,
}
}
pub fn warn_legacy_once(legacy_name: &'static str, new_name: &'static str) {
let mut warned = match WARNED.lock() {
Ok(g) => g,
Err(poisoned) => poisoned.into_inner(),
};
if warned.insert(legacy_name) {
eprintln!(
"[socket-patch] warning: env var `{legacy_name}` is deprecated; \
use `{new_name}` instead. The legacy name will be removed in a \
future major release."
);
}
}
pub const LEGACY_ENV_RENAMES: &[(&str, &str)] = &[
("SOCKET_PROXY_URL", "SOCKET_PATCH_PROXY_URL"),
("SOCKET_DEBUG", "SOCKET_PATCH_DEBUG"),
("SOCKET_TELEMETRY_DISABLED", "SOCKET_PATCH_TELEMETRY_DISABLED"),
];
pub fn promote_legacy_env_vars() {
for (new_name, legacy_name) in LEGACY_ENV_RENAMES {
let new_already_set = std::env::var(new_name)
.ok()
.filter(|v| !v.is_empty())
.is_some();
if new_already_set {
continue;
}
if let Ok(value) = std::env::var(legacy_name) {
if !value.is_empty() {
warn_legacy_once(legacy_name, new_name);
std::env::set_var(new_name, value);
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn warn_legacy_once_fires_only_once_per_name() {
let name = "SOCKET_TEST_LEGACY_ONCE_PATCH";
let new = "SOCKET_TEST_LEGACY_ONCE";
warn_legacy_once(name, new);
warn_legacy_once(name, new);
let warned = WARNED.lock().unwrap();
assert!(warned.contains(name));
}
}