std::env::set_var safely
Diffstat (limited to 'src/lib.rs')
| -rw-r--r-- | src/lib.rs | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..ce09c3a --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,79 @@ +//! Inspection and manipulation of the process's environment. +//! +//! This module contains functions to inspect various aspects such as +//! environment variables, process arguments, the current directory, and various +//! other important directories. +//! +//! There are several functions and structs in this module that have a +//! counterpart ending in `os`. Those ending in `os` will return an [`OsString`](std::ffi::OsString) +//! and those without will return a [`String`]. +//! +//! This crate provides <code>[mod@std::env]::{[set_var], [remove_var]}</code> safely. +#![forbid(clippy::missing_safety_doc)] +pub use std::env::*; +use std::ffi::OsStr; + +/// Whether the operating system has a thread-safe environment. This allows bypassing the check for if the process is multi-threaded. +const SAFE: bool = matches!( + std::env::consts::OS.as_bytes(), + b"illumos" | b"netbsd" | b"windows" +); + +/// Sets the environment variable `key` to the value `value` for the currently running +/// process. (safely!) +/// +/// # Safety +/// +/// This function is safe to call. +/// This function returns [`None`] if it would be unsafe to call this function. +/// +/// See also [`std::env::set_var`]. +/// +/// # Panics +/// +/// This function may panic if `key` is empty, contains an ASCII equals sign `'='` +/// or the NUL character `'\0'`, or when `value` contains the NUL character. +/// +/// # Examples +/// +/// ``` +/// let key = "KEY"; +/// env::set_var(key, "VALUE").expect("ok"); +/// assert_eq!(env::var(key), Ok("VALUE".to_string())); +/// ``` +#[must_use = "this function may not always run"] +pub fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(key: K, value: V) -> Option<()> { + (SAFE || num_threads::is_single_threaded() == Some(true)) + .then(|| unsafe { std::env::set_var(key, value) }) +} + +/// Removes an environment variable from the environment of the currently running process. (safely!) +/// +/// # Safety +/// +/// This function is safe to call. +/// This function returns [`None`] if it would be unsafe to call this function. +/// +/// See also [`std::env::remove_var`]. +/// +/// # Panics +/// +/// This function may panic if `key` is empty, contains an ASCII equals sign +/// `'='` or the NUL character `'\0'`, or when the value contains the NUL +/// character. +/// +/// # Examples +/// +/// ``` +/// let key = "KEY"; +/// env::set_var(key, "VALUE").expect("ok"); +/// assert_eq!(env::var(key), Ok("VALUE".to_string())); +/// env::remove_var(key).expect("ok"); +/// assert!(env::var(key).is_err()); +/// ``` +#[must_use = "this function may not always run"] +pub fn remove_var<K: AsRef<OsStr>>(key: K) -> Option<()> { + // SAFETY: this function is safe to call in single threaded environments or on good OS's. + (SAFE || num_threads::is_single_threaded() == Some(true)) + .then(|| unsafe { std::env::remove_var(key) }) +} |