whoami/
os.rs

1#![allow(unsafe_code)]
2
3// Daku
4#[cfg_attr(
5    all(target_arch = "wasm32", target_os = "daku"),
6    path = "os/daku.rs"
7)]
8// Redox
9#[cfg_attr(
10    all(target_os = "redox", not(target_arch = "wasm32")),
11    path = "os/redox.rs"
12)]
13// Unix
14#[cfg_attr(
15    all(
16        any(
17            target_os = "linux",
18            target_os = "macos",
19            target_os = "dragonfly",
20            target_os = "freebsd",
21            target_os = "netbsd",
22            target_os = "openbsd",
23            target_os = "illumos",
24        ),
25        not(target_arch = "wasm32")
26    ),
27    path = "os/unix.rs"
28)]
29// Wasi
30#[cfg_attr(
31    all(target_arch = "wasm32", target_os = "wasi"),
32    path = "os/wasi.rs"
33)]
34// Web
35#[cfg_attr(
36    all(
37        target_arch = "wasm32",
38        not(target_os = "wasi"),
39        not(target_os = "daku"),
40        feature = "web",
41    ),
42    path = "os/web.rs"
43)]
44// Windows
45#[cfg_attr(
46    all(target_os = "windows", not(target_arch = "wasm32")),
47    path = "os/windows.rs"
48)]
49mod target;
50
51use std::{
52    env::{self, VarError},
53    ffi::OsString,
54    io::{Error, ErrorKind},
55};
56
57use crate::{Arch, DesktopEnv, Platform, Result};
58
59/// Implement `Target for Os` to add platform support for a target.
60pub(crate) struct Os;
61
62/// Target platform support
63pub(crate) trait Target: Sized {
64    /// Return a semicolon-delimited string of language/COUNTRY codes.
65    fn langs(self) -> Result<String>;
66    /// Return the user's "real" / "full" name.
67    fn realname(self) -> Result<OsString>;
68    /// Return the user's username.
69    fn username(self) -> Result<OsString>;
70    /// Return the computer's "fancy" / "pretty" name.
71    fn devicename(self) -> Result<OsString>;
72    /// Return the computer's hostname.
73    fn hostname(self) -> Result<String>;
74    /// Return the OS distribution's name.
75    fn distro(self) -> Result<String>;
76    /// Return the desktop environment.
77    fn desktop_env(self) -> DesktopEnv;
78    /// Return the target platform.
79    fn platform(self) -> Platform;
80    /// Return the computer's CPU architecture.
81    fn arch(self) -> Result<Arch>;
82
83    /// Return the user's account name (usually just the username, but may
84    /// include an account server hostname).
85    fn account(self) -> Result<OsString> {
86        self.username()
87    }
88}
89
90// This is only used on some platforms
91#[allow(dead_code)]
92fn err_missing_record() -> Error {
93    Error::new(ErrorKind::NotFound, "Missing record")
94}
95
96// This is only used on some platforms
97#[allow(dead_code)]
98fn err_null_record() -> Error {
99    Error::new(ErrorKind::NotFound, "Null record")
100}
101
102// This is only used on some platforms
103#[allow(dead_code)]
104fn err_empty_record() -> Error {
105    Error::new(ErrorKind::NotFound, "Empty record")
106}
107
108// This is only used on some platforms
109#[allow(dead_code)]
110fn unix_lang() -> Result<String> {
111    let check_var = |var| {
112        env::var(var).map_err(|e| {
113            let kind = match e {
114                VarError::NotPresent => ErrorKind::NotFound,
115                VarError::NotUnicode(_) => ErrorKind::InvalidData,
116            };
117            Error::new(kind, e)
118        })
119    };
120    let langs = check_var("LANGS").or_else(|_| check_var("LANG"))?;
121
122    if langs.is_empty() {
123        return Err(err_empty_record());
124    }
125
126    Ok(langs)
127}