env/
lib.rs

1//! Inspection and manipulation of the process's environment.
2//!
3//! This module contains functions to inspect various aspects such as
4//! environment variables, process arguments, the current directory, and various
5//! other important directories.
6//!
7//! There are several functions and structs in this module that have a
8//! counterpart ending in `os`. Those ending in `os` will return an [`OsString`](std::ffi::OsString)
9//! and those without will return a [`String`].
10//!
11//! This crate provides <code>[mod@std::env]::{[set_var], [remove_var]}</code> safely.
12#![forbid(clippy::missing_safety_doc)]
13pub use std::env::*;
14use std::ffi::OsStr;
15
16/// Whether the operating system has a thread-safe environment. This allows bypassing the check for if the process is multi-threaded.
17const SAFE: bool = matches!(
18    std::env::consts::OS.as_bytes(),
19    b"illumos" | b"netbsd" | b"windows"
20);
21
22/// Sets the environment variable `key` to the value `value` for the currently running
23/// process. (safely!)
24///
25/// # Safety
26///
27/// This function is safe to call.
28/// This function returns [`None`] if it would be unsafe to call this function.
29///
30/// See also [`std::env::set_var`].
31///
32/// # Panics
33///
34/// This function may panic if `key` is empty, contains an ASCII equals sign `'='`
35/// or the NUL character `'\0'`, or when `value` contains the NUL character.
36///
37/// # Examples
38///
39/// ```
40/// let key = "KEY";
41/// env::set_var(key, "VALUE").expect("ok");
42/// assert_eq!(env::var(key), Ok("VALUE".to_string()));
43/// ```
44#[must_use = "this function may not always run"]
45pub fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(key: K, value: V) -> Option<()> {
46    (SAFE || num_threads::is_single_threaded() == Some(true))
47        .then(|| unsafe { std::env::set_var(key, value) })
48}
49
50/// Removes an environment variable from the environment of the currently running process. (safely!)
51///
52/// # Safety
53///
54/// This function is safe to call.
55/// This function returns [`None`] if it would be unsafe to call this function.
56///
57/// See also [`std::env::remove_var`].
58///
59/// # Panics
60///
61/// This function may panic if `key` is empty, contains an ASCII equals sign
62/// `'='` or the NUL character `'\0'`, or when the value contains the NUL
63/// character.
64///
65/// # Examples
66///
67/// ```
68/// let key = "KEY";
69/// env::set_var(key, "VALUE").expect("ok");
70/// assert_eq!(env::var(key), Ok("VALUE".to_string()));
71/// env::remove_var(key).expect("ok");
72/// assert!(env::var(key).is_err());
73/// ```
74#[must_use = "this function may not always run"]
75pub fn remove_var<K: AsRef<OsStr>>(key: K) -> Option<()> {
76    // SAFETY: this function is safe to call in single threaded environments or on good OS's.
77    (SAFE || num_threads::is_single_threaded() == Some(true))
78        .then(|| unsafe { std::env::remove_var(key) })
79}