devela/sys/env/
namespace.rs

1// devela::sys::env::env
2//
3//! Defines the [`Env`] struct namespace.
4//
5// TOC
6// - Constants
7// - Command line arguments
8// - Environment variables
9// - Paths
10
11#[cfg(all(feature = "std", feature = "unsafe_thread"))]
12use crate::_dep::_std::env::{remove_var, set_var};
13#[allow(deprecated, reason = "home_dir()")] // WAIT: 1.86?
14#[cfg(feature = "std")]
15use crate::{
16    IoResult, IterArgs, IterArgsOs, IterSplitPaths, IterVars, IterVarsOs, JoinPathsError, OsStr,
17    OsString, Path, PathBuf, VarError,
18    _dep::_std::env::{
19        args, args_os, current_dir, current_exe, home_dir, join_paths, set_current_dir,
20        split_paths, temp_dir, var, var_os, vars, vars_os,
21    },
22};
23
24#[doc = crate::TAG_NAMESPACE!()]
25/// A namespaced wrapper for `std::env` functions and constants.
26pub struct Env;
27
28/// # Constants
29/*
30The lists of expected values for not(std) configuration flags can be copied from:
31<https://github.com/rust-lang/rust/blob/master/tests/ui/check-cfg/well-known-values.stderr>.
32Afterwards they can be procesed with vim commands similar to:
33s/`//g
34s/, /\r/g
35s/\([a-z0-9_.]\+\)/#[cfg(target_arch = "\1")]\r{ "\1" }/
36s/\([a-z0-9_.]\+\)/target_arch = "\1",/
37*/
38impl Env {
39    #[doc = crate::TAG_MAYBE_STD!()]
40    /// A string describing the architecture of the CPU that is currently in use.
41    ///
42    /// Expected values are:
43    /// `aarch64`, `arm`, `arm64ec`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`, and `xtensa`.
44    #[rustfmt::skip]
45    pub const ARCH: &'static str = {
46        #[cfg(feature = "std")]
47        { std::env::consts::ARCH }
48        #[cfg(not(feature = "std"))]
49        { // 27 arches:
50            #[cfg(target_arch = "aarch64")]
51            { "aarch64" }
52            #[cfg(target_arch = "arm")]
53            { "arm" }
54            #[cfg(target_arch = "arm64ec")]
55            { "arm64ec" }
56            #[cfg(target_arch = "avr")]
57            { "avr" }
58            #[cfg(target_arch = "bpf")]
59            { "bpf" }
60            #[cfg(target_arch = "csky")]
61            { "csky" }
62            #[cfg(target_arch = "hexagon")]
63            { "hexagon" }
64            #[cfg(target_arch = "loongarch64")]
65            { "loongarch64" }
66            #[cfg(target_arch = "m68k")]
67            { "m68k" }
68            #[cfg(target_arch = "mips")]
69            { "mips" }
70            #[cfg(target_arch = "mips32r6")]
71            { "mips32r6" }
72            #[cfg(target_arch = "mips64")]
73            { "mips64" }
74            #[cfg(target_arch = "mips64r6")]
75            { "mips64r6" }
76            #[cfg(target_arch = "msp430")]
77            { "msp430" }
78            #[cfg(target_arch = "nvptx64")]
79            { "nvptx64" }
80            #[cfg(target_arch = "powerpc")]
81            { "powerpc" }
82            #[cfg(target_arch = "powerpc64")]
83            { "powerpc64" }
84            #[cfg(target_arch = "riscv32")]
85            { "riscv32" }
86            #[cfg(target_arch = "riscv64")]
87            { "riscv64" }
88            #[cfg(target_arch = "s390x")]
89            { "s390x" }
90            #[cfg(target_arch = "sparc")]
91            { "sparc" }
92            #[cfg(target_arch = "sparc64")]
93            { "sparc64" }
94            #[cfg(target_arch = "wasm32")]
95            { "wasm32" }
96            #[cfg(target_arch = "wasm64")]
97            { "wasm64" }
98            #[cfg(target_arch = "x86")]
99            { "x86" }
100            #[cfg(target_arch = "x86_64")]
101            { "x86_64" }
102            #[cfg(target_arch = "xtensa")]
103            { "xtensa" }
104            #[cfg(not(any(
105                target_arch = "aarch64",
106                target_arch = "arm",
107                target_arch = "arm64ec",
108                target_arch = "avr",
109                target_arch = "bpf",
110                target_arch = "csky",
111                target_arch = "hexagon",
112                target_arch = "loongarch64",
113                target_arch = "m68k",
114                target_arch = "mips",
115                target_arch = "mips32r6",
116                target_arch = "mips64",
117                target_arch = "mips64r6",
118                target_arch = "msp430",
119                target_arch = "nvptx64",
120                target_arch = "powerpc",
121                target_arch = "powerpc64",
122                target_arch = "riscv32",
123                target_arch = "riscv64",
124                target_arch = "s390x",
125                target_arch = "sparc",
126                target_arch = "sparc64",
127                target_arch = "wasm32",
128                target_arch = "wasm64",
129                target_arch = "x86",
130                target_arch = "x86_64",
131                target_arch = "xtensa",
132            )))]
133            { "unknown" }
134        }
135    };
136
137    #[doc = crate::TAG_MAYBE_STD!()]
138    /// The family of the operating system.
139    ///
140    /// The expected values are: `unix`, `wasm`, and `windows`
141    #[rustfmt::skip]
142    pub const FAMILY: &'static str = {
143        #[cfg(feature = "std")]
144        { std::env::consts::FAMILY }
145        #[cfg(not(feature = "std"))]
146        {
147            #[cfg(target_family = "unix")]
148            { "unix" }
149            #[cfg(target_family = "wasm")]
150            { "wasm" }
151            #[cfg(target_family = "windows")]
152            { "windows" }
153            #[cfg(not(any(
154                target_family = "unix",
155                target_family = "wasm",
156                target_family = "windows",
157            )))]
158            { "unknown" }
159        }
160    };
161
162    /// A string describing the vendor of the CPU that is currently in use.
163    ///
164    /// Expected values are:
165    ///  `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`.
166    #[rustfmt::skip]
167    pub const VENDOR: &'static str = { // 15 vendors
168        #[cfg(target_vendor = "apple")]
169        { "apple" }
170        #[cfg(target_vendor = "espressif")]
171        { "espressif" }
172        #[cfg(target_vendor = "fortanix")]
173        { "fortanix" }
174        #[cfg(target_vendor = "ibm")]
175        { "ibm" }
176        #[cfg(target_vendor = "kmc")]
177        { "kmc" }
178        #[cfg(target_vendor = "nintendo")]
179        { "nintendo" }
180        #[cfg(target_vendor = "nvidia")]
181        { "nvidia" }
182        #[cfg(target_vendor = "pc")]
183        { "pc" }
184        #[cfg(target_vendor = "risc0")]
185        { "risc0" }
186        #[cfg(target_vendor = "sony")]
187        { "sony" }
188        #[cfg(target_vendor = "sun")]
189        { "sun" }
190        #[cfg(target_vendor = "unikraft")]
191        { "unikraft" }
192        #[cfg(target_vendor = "uwp")]
193        { "uwp" }
194        #[cfg(target_vendor = "win7")]
195        { "win7" }
196        #[cfg(target_vendor = "wrs")]
197        { "wrs" }
198        #[cfg(not(any(
199            target_vendor = "apple",
200            target_vendor = "espressif",
201            target_vendor = "fortanix",
202            target_vendor = "ibm",
203            target_vendor = "kmc",
204            target_vendor = "nintendo",
205            target_vendor = "nvidia",
206            target_vendor = "pc",
207            target_vendor = "risc0",
208            target_vendor = "sony",
209            target_vendor = "sun",
210            target_vendor = "unikraft",
211            target_vendor = "uwp",
212            target_vendor = "win7",
213            target_vendor = "wrs",
214        )))]
215        { "unknown" }
216    };
217
218    #[doc = crate::TAG_MAYBE_STD!()]
219    /// A string describing the specific operating system in use.
220    ///
221    /// The expected values are:
222    /// `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`.
223    #[rustfmt::skip]
224    pub const OS: &'static str = {
225        #[cfg(feature = "std")]
226        { std::env::consts::OS }
227        #[cfg(not(feature = "std"))]
228        { // 40 oses:
229            #[cfg(target_os = "aix")]
230            { "aix" }
231            #[cfg(target_os = "android")]
232            { "android" }
233            #[cfg(target_os = "cuda")]
234            { "cuda" }
235            #[cfg(target_os = "dragonfly")]
236            { "dragonfly" }
237            #[cfg(target_os = "emscripten")]
238            { "emscripten" }
239            #[cfg(target_os = "espidf")]
240            { "espidf" }
241            #[cfg(target_os = "freebsd")]
242            { "freebsd" }
243            #[cfg(target_os = "fuchsia")]
244            { "fuchsia" }
245            #[cfg(target_os = "haiku")]
246            { "haiku" }
247            #[cfg(target_os = "hermit")]
248            { "hermit" }
249            #[cfg(target_os = "horizon")]
250            { "horizon" }
251            #[cfg(target_os = "hurd")]
252            { "hurd" }
253            #[cfg(target_os = "illumos")]
254            { "illumos" }
255            #[cfg(target_os = "ios")]
256            { "ios" }
257            #[cfg(target_os = "l4re")]
258            { "l4re" }
259            #[cfg(target_os = "linux")]
260            { "linux" }
261            #[cfg(target_os = "macos")]
262            { "macos" }
263            #[cfg(target_os = "netbsd")]
264            { "netbsd" }
265            #[cfg(target_os = "none")]
266            { "none" }
267            #[cfg(target_os = "nto")]
268            { "nto" }
269            #[cfg(target_os = "nuttx")]
270            { "nuttx" }
271            #[cfg(target_os = "openbsd")]
272            { "openbsd" }
273            #[cfg(target_os = "psp")]
274            { "psp" }
275            // WAIT: 1.84
276            // #[cfg(target_os = "psx")]
277            // { "psx" }
278            #[cfg(target_os = "redox")]
279            { "redox" }
280            #[cfg(target_os = "rtems")]
281            { "rtems" }
282            #[cfg(target_os = "solaris")]
283            { "solaris" }
284            #[cfg(target_os = "solid_asp3")]
285            { "solid_asp3" }
286            #[cfg(target_os = "teeos")]
287            { "teeos" }
288            #[cfg(target_os = "trusty")]
289            { "trusty" }
290            #[cfg(target_os = "tvos")]
291            { "tvos" }
292            #[cfg(target_os = "uefi")]
293            { "uefi" }
294            #[cfg(target_os = "unknown")]
295            { "unknown" }
296            #[cfg(target_os = "visionos")]
297            { "visionos" }
298            #[cfg(target_os = "vita")]
299            { "vita" }
300            #[cfg(target_os = "vxworks")]
301            { "vxworks" }
302            #[cfg(target_os = "wasi")]
303            { "wasi" }
304            #[cfg(target_os = "watchos")]
305            { "watchos" }
306            #[cfg(target_os = "windows")]
307            { "windows" }
308            #[cfg(target_os = "xous")]
309            { "xous" }
310            #[cfg(target_os = "zkvm")]
311            { "zkvm" }
312            #[cfg(not(any(
313                target_os = "aix",
314                target_os = "android",
315                target_os = "cuda",
316                target_os = "dragonfly",
317                target_os = "emscripten",
318                target_os = "espidf",
319                target_os = "freebsd",
320                target_os = "fuchsia",
321                target_os = "haiku",
322                target_os = "hermit",
323                target_os = "horizon",
324                target_os = "hurd",
325                target_os = "illumos",
326                target_os = "ios",
327                target_os = "l4re",
328                target_os = "linux",
329                target_os = "macos",
330                target_os = "netbsd",
331                target_os = "none",
332                target_os = "nto",
333                target_os = "nuttx",
334                target_os = "openbsd",
335                target_os = "psp",
336                // WAIT: 1.84
337                // target_os = "psx",
338                target_os = "redox",
339                target_os = "rtems",
340                target_os = "solaris",
341                target_os = "solid_asp3",
342                target_os = "teeos",
343                target_os = "trusty",
344                target_os = "tvos",
345                target_os = "uefi",
346                target_os = "unknown",
347                target_os = "visionos",
348                target_os = "vita",
349                target_os = "vxworks",
350                target_os = "wasi",
351                target_os = "watchos",
352                target_os = "windows",
353                target_os = "xous",
354                target_os = "zkvm",
355            )))]
356            { "unknown" }
357        }
358    };
359
360    /// Specifies the file extension used for shared libraries on this platform
361    /// that goes after the dot.
362    ///
363    /// Some possible values:
364    /// - `so`
365    /// - `dylib`
366    /// - `dll`
367    #[cfg(feature = "std")]
368    #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "std")))]
369    pub const DLL_EXTENSION: &'static str = std::env::consts::DLL_EXTENSION;
370
371    /// Specifies the filename prefix used for shared libraries on this platform.
372    ///
373    /// Some possible values:
374    /// - `lib`
375    /// - `` (an empty string)
376    #[cfg(feature = "std")]
377    #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "std")))]
378    pub const DLL_PREFIX: &'static str = std::env::consts::DLL_PREFIX;
379
380    /// Specifies the filename suffix used for shared libraries on this platform.
381    ///
382    /// Some possible values:
383    /// - `.so`
384    /// - `.dylib`
385    /// - `.dll`
386    #[cfg(feature = "std")]
387    #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "std")))]
388    pub const DLL_SUFFIX: &'static str = std::env::consts::DLL_SUFFIX;
389
390    /// Specifies the file extension, if any, used for executable binaries on this platform.
391    ///
392    /// Some possible values:
393    /// - `exe`
394    /// - `` (an empty string)
395    #[cfg(feature = "std")]
396    #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "std")))]
397    pub const EXE_EXTENSION: &'static str = std::env::consts::EXE_EXTENSION;
398
399    /// Specifies the filename suffix used for executable binaries on this platform.
400    ///
401    /// Some possible values:
402    /// - `.exe`
403    /// - `.nexe`
404    /// - `.pexe`
405    /// - `` (an empty string)
406    #[cfg(feature = "std")]
407    #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "std")))]
408    pub const EXE_SUFFIX: &'static str = std::env::consts::EXE_SUFFIX;
409}
410
411/// # Command line arguments
412#[cfg(feature = "std")]
413#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "std")))]
414impl Env {
415    /// Returns the arguments that this program was started with.
416    ///
417    /// See [args].
418    pub fn args() -> IterArgs {
419        args()
420    }
421
422    /// See [args_os].
423    pub fn args_os() -> IterArgsOs {
424        args_os()
425    }
426}
427
428/// # Environment variables
429#[cfg(feature = "std")]
430#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "std")))]
431impl Env {
432    /// Fetches the environment variable key from the current process.
433    ///
434    /// See [var].
435    pub fn var<K: AsRef<OsStr>>(key: K) -> Result<String, VarError> {
436        var(key)
437    }
438
439    /// Returns an iterator of (variable, value) pairs of strings,
440    /// for all the environment variables of the current process.
441    ///
442    /// See [vars].
443    pub fn vars() -> IterVars {
444        vars()
445    }
446
447    /// Fetches the environment variable key from the current process.
448    ///
449    /// See [var_os].
450    pub fn var_os<K: AsRef<OsStr>>(key: K) -> Option<OsString> {
451        var_os(key)
452    }
453
454    /// Returns an iterator of (variable, value) pairs of OS strings,
455    /// for all the environment variables of the current process.
456    ///
457    /// See [vars_os].
458    pub fn vars_os() -> IterVarsOs {
459        vars_os()
460    }
461
462    /// Removes the environment variable `key` from the environment
463    /// of the currently running process.
464    ///
465    /// # Safety
466    /// See [remove_var].
467    #[cfg(all(not(feature = "safe_sys"), feature = "unsafe_thread"))]
468    #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "unsafe_thread")))]
469    pub unsafe fn remove_var<K: AsRef<OsStr>>(key: K) {
470        unsafe { remove_var(key) }
471    }
472
473    /// Sets the environment variable `key` to the value `value`
474    /// for the currently running process.
475    ///
476    /// # Safety
477    /// See [set_var].
478    #[cfg(all(not(feature = "safe_sys"), feature = "unsafe_thread"))]
479    #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "unsafe_thread")))]
480    pub unsafe fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(key: K, value: V) {
481        unsafe { set_var(key, value) }
482    }
483}
484
485/// # Paths
486#[cfg(feature = "std")]
487#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "std")))]
488impl Env {
489    /// Returns the full filesystem path of the current running executable.
490    ///
491    /// See [current_exe].
492    pub fn current_exe() -> IoResult<PathBuf> {
493        current_exe()
494    }
495
496    /// Returns the current working directory.
497    ///
498    /// See [current_dir].
499    pub fn current_dir() -> IoResult<PathBuf> {
500        current_dir()
501    }
502
503    /// Changes the current working directory to the specified path.
504    ///
505    /// See [set_current_dir].
506    pub fn set_current_dir<P: AsRef<Path>>(path: P) -> IoResult<()> {
507        set_current_dir(path)
508    }
509
510    /// Returns the path of the current user’s home directory if known.
511    ///
512    /// See [home_dir].
513    // WAIT: 1.86? https://blog.rust-lang.org/2025/02/20/Rust-1.85.0.html#updates-to-stdenvhome_dir
514    #[allow(deprecated)]
515    pub fn home_dir() -> Option<PathBuf> {
516        home_dir()
517    }
518
519    /// Returns the path of a temporary directory.
520    ///
521    /// See [temp_dir].
522    pub fn temp_dir() -> PathBuf {
523        temp_dir()
524    }
525
526    /// Joins a collection of [Path]s appropriately for the `PATH` environment variable.
527    ///
528    /// See [join_paths].
529    pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
530    where
531        I: IntoIterator<Item = T>,
532        T: AsRef<OsStr>,
533    {
534        join_paths(paths)
535    }
536
537    /// Parses input according to platform conventions for the `PATH` environment variable.
538    ///
539    /// See [split_paths].
540    pub fn split_paths<T: AsRef<OsStr> + ?Sized>(unparsed: &T) -> IterSplitPaths<'_> {
541        split_paths(unparsed)
542    }
543}