1#![allow(unsafe_code)]
2
3#[cfg_attr(
5 all(target_arch = "wasm32", target_os = "daku"),
6 path = "os/daku.rs"
7)]
8#[cfg_attr(
10 all(target_os = "redox", not(target_arch = "wasm32")),
11 path = "os/redox.rs"
12)]
13#[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#[cfg_attr(
31 all(target_arch = "wasm32", target_os = "wasi"),
32 path = "os/wasi.rs"
33)]
34#[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#[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
59pub(crate) struct Os;
61
62pub(crate) trait Target: Sized {
64 fn langs(self) -> Result<String>;
66 fn realname(self) -> Result<OsString>;
68 fn username(self) -> Result<OsString>;
70 fn devicename(self) -> Result<OsString>;
72 fn hostname(self) -> Result<String>;
74 fn distro(self) -> Result<String>;
76 fn desktop_env(self) -> DesktopEnv;
78 fn platform(self) -> Platform;
80 fn arch(self) -> Result<Arch>;
82
83 fn account(self) -> Result<OsString> {
86 self.username()
87 }
88}
89
90#[allow(dead_code)]
92fn err_missing_record() -> Error {
93 Error::new(ErrorKind::NotFound, "Missing record")
94}
95
96#[allow(dead_code)]
98fn err_null_record() -> Error {
99 Error::new(ErrorKind::NotFound, "Null record")
100}
101
102#[allow(dead_code)]
104fn err_empty_record() -> Error {
105 Error::new(ErrorKind::NotFound, "Empty record")
106}
107
108#[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}