use super::{Context, Module, ModuleConfig};
use crate::configs::os::OSConfig;
use crate::formatter::StringFormatter;
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
let mut module = context.new_module("os");
let config: OSConfig = OSConfig::try_load(module.config);
if config.disabled {
return None;
}
#[cfg(not(test))]
let os = os_info::get();
#[cfg(test)]
let os = os_info::Info::default();
let parsed = StringFormatter::new(config.format).and_then(|formatter| {
formatter
.map_meta(|variable, _| match variable {
"symbol" => get_symbol(&config, &os.os_type()),
_ => None,
})
.map_style(|variable| match variable {
"style" => Some(Ok(config.style)),
_ => None,
})
.map(|variable| match variable {
"codename" => get_codename(&os).map(Ok),
"edition" => get_edition(&os).map(Ok),
"name" => get_name(&os).map(Ok),
"type" => get_type(&os).map(Ok),
"version" => get_version(&os).map(Ok),
_ => None,
})
.parse(None, Some(context))
});
module.set_segments(match parsed {
Ok(segments) => segments,
Err(error) => {
log::warn!("Error in module `os`:\n{}", error);
return None;
}
});
Some(module)
}
fn get_symbol<'a>(config: &'a OSConfig, os_type: &os_info::Type) -> Option<&'a str> {
config
.get_symbol(os_type)
.or_else(|| OSConfig::default().get_symbol(os_type))
}
fn get_codename(os: &os_info::Info) -> Option<String> {
os.codename().map(String::from)
}
fn get_edition(os: &os_info::Info) -> Option<String> {
os.edition().map(String::from)
}
fn get_name(os: &os_info::Info) -> Option<String> {
Some(os.os_type().to_string())
}
fn get_type(os: &os_info::Info) -> Option<String> {
Some(format!("{:?}", os.os_type()))
}
fn get_version(os: &os_info::Info) -> Option<String> {
Some(os.version())
.filter(|&x| x != &os_info::Version::Unknown)
.map(|x| x.to_string())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test::ModuleRenderer;
use nu_ansi_term::Color;
use os_info::Type;
#[test]
fn default() {
let actual = ModuleRenderer::new("os").collect();
assert_eq!(actual, None);
}
#[test]
fn default_enabled() {
let actual = ModuleRenderer::new("os")
.config(toml::toml! {
[os]
disabled = false
})
.collect();
let expected = Some(format!("{}", Color::White.bold().paint("โ ")));
assert_eq!(actual, expected);
}
#[test]
fn all_segments() {
let actual = ModuleRenderer::new("os")
.config(toml::toml! {
[os]
disabled = false
format = "[$symbol($codename )($edition )($name )($type )($version )]($style)"
})
.collect();
let expected = Some(format!(
"{}",
Color::White.bold().paint("โ Unknown Unknown ")
));
assert_eq!(actual, expected);
}
#[test]
fn get_symbol_default() {
let config = OSConfig::try_load(None);
let type_expected_pairs = [
(Type::Alpine, Some("๐๏ธ ")),
(Type::Amazon, Some("๐ ")),
(Type::Android, Some("๐ค ")),
(Type::Arch, Some("๐๏ธ ")),
(Type::CentOS, Some("๐ ")),
(Type::Debian, Some("๐ ")),
(Type::DragonFly, Some("๐ ")),
(Type::Emscripten, Some("๐ ")),
(Type::EndeavourOS, Some("๐ ")),
(Type::Fedora, Some("๐ฉ ")),
(Type::FreeBSD, Some("๐ ")),
(Type::Garuda, Some("๐ฆ
")),
(Type::Gentoo, Some("๐๏ธ ")),
(Type::HardenedBSD, Some("๐ก๏ธ ")),
(Type::Illumos, Some("๐ฆ ")),
(Type::Linux, Some("๐ง ")),
(Type::Macos, Some("๐ ")),
(Type::Manjaro, Some("๐ฅญ ")),
(Type::Mariner, Some("๐ ")),
(Type::MidnightBSD, Some("๐ ")),
(Type::Mint, Some("๐ฟ ")),
(Type::NetBSD, Some("๐ฉ ")),
(Type::NixOS, Some("โ๏ธ ")),
(Type::OpenBSD, Some("๐ก ")),
(Type::openSUSE, Some("๐ฆ ")),
(Type::OracleLinux, Some("๐ฆด ")),
(Type::Pop, Some("๐ญ ")),
(Type::Raspbian, Some("๐ ")),
(Type::Redhat, Some("๐ฉ ")),
(Type::RedHatEnterprise, Some("๐ฉ ")),
(Type::Redox, Some("๐งช ")),
(Type::Solus, Some("โต ")),
(Type::SUSE, Some("๐ฆ ")),
(Type::Ubuntu, Some("๐ฏ ")),
(Type::Unknown, Some("โ ")),
(Type::Windows, Some("๐ช ")),
];
for (t, e) in type_expected_pairs {
assert_eq!(get_symbol(&config, &t), e);
}
}
#[test]
fn get_symbol_custom() {
let config_toml = toml::toml! {
[symbols]
Alpine = "๏ "
Amazon = "๏ฐ "
Android = "๏
ป "
Arch = "๏ "
CentOS = "๏ "
Debian = "๏ "
DragonFly = "๎ "
Emscripten = "๏
"
EndeavourOS = "๏ "
Fedora = "๏ "
FreeBSD = "๏ "
Garuda = "๏ฏ "
Gentoo = "๏ "
HardenedBSD = "๏ฒ "
Illumos = "๏ท "
Linux = "๏ "
Macos = "๏ "
Manjaro = "๏ "
Mariner = "๏ "
MidnightBSD = "๏ "
Mint = "๏ "
NetBSD = "๏ค "
NixOS = "๏ "
OpenBSD = "๏น "
SUSE = "๏ "
OracleLinux = "๏ ถ "
Pop = "๎ฃ "
Raspbian = "๏ "
Redhat = "๏ "
RedHatEnterprise = "๏ "
Redox = "๏ "
Solus = "๏ดฑ "
openSUSE = "๏ "
Ubuntu = "๏ "
Unknown = "๏ญ "
Windows = "๏กฑ "
};
let config = OSConfig::load(&config_toml);
let type_expected_pairs = [
(Type::Alpine, Some("๏ ")),
(Type::Amazon, Some("๏ฐ ")),
(Type::Android, Some("๏
ป ")),
(Type::Arch, Some("๏ ")),
(Type::CentOS, Some("๏ ")),
(Type::Debian, Some("๏ ")),
(Type::DragonFly, Some("๎ ")),
(Type::Emscripten, Some("๏
")),
(Type::EndeavourOS, Some("๏ ")),
(Type::Fedora, Some("๏ ")),
(Type::FreeBSD, Some("๏ ")),
(Type::Garuda, Some("๏ฏ ")),
(Type::Gentoo, Some("๏ ")),
(Type::HardenedBSD, Some("๏ฒ ")),
(Type::Illumos, Some("๏ท ")),
(Type::Linux, Some("๏ ")),
(Type::Macos, Some("๏ ")),
(Type::Manjaro, Some("๏ ")),
(Type::Mariner, Some("๏ ")),
(Type::MidnightBSD, Some("๏ ")),
(Type::Mint, Some("๏ ")),
(Type::NetBSD, Some("๏ค ")),
(Type::NixOS, Some("๏ ")),
(Type::OpenBSD, Some("๏น ")),
(Type::SUSE, Some("๏ ")),
(Type::OracleLinux, Some("๏ ถ ")),
(Type::Pop, Some("๎ฃ ")),
(Type::Raspbian, Some("๏ ")),
(Type::Redhat, Some("๏ ")),
(Type::RedHatEnterprise, Some("๏ ")),
(Type::Redox, Some("๏ ")),
(Type::Solus, Some("๏ดฑ ")),
(Type::openSUSE, Some("๏ ")),
(Type::Ubuntu, Some("๏ ")),
(Type::Unknown, Some("๏ญ ")),
(Type::Windows, Some("๏กฑ ")),
];
for (t, e) in type_expected_pairs {
assert_eq!(get_symbol(&config, &t), e);
}
}
#[test]
fn get_symbol_fallback() {
let config_toml = toml::toml! {
[symbols]
Unknown = ""
Arch = "Arch is the best!"
};
let config = OSConfig::load(&config_toml);
let type_expected_pairs = [
(Type::Alpine, Some("๐๏ธ ")),
(Type::Amazon, Some("๐ ")),
(Type::Android, Some("๐ค ")),
(Type::Arch, Some("Arch is the best!")),
(Type::CentOS, Some("๐ ")),
(Type::Debian, Some("๐ ")),
(Type::DragonFly, Some("๐ ")),
(Type::Emscripten, Some("๐ ")),
(Type::EndeavourOS, Some("๐ ")),
(Type::Fedora, Some("๐ฉ ")),
(Type::FreeBSD, Some("๐ ")),
(Type::Garuda, Some("๐ฆ
")),
(Type::Gentoo, Some("๐๏ธ ")),
(Type::HardenedBSD, Some("๐ก๏ธ ")),
(Type::Illumos, Some("๐ฆ ")),
(Type::Linux, Some("๐ง ")),
(Type::Macos, Some("๐ ")),
(Type::Manjaro, Some("๐ฅญ ")),
(Type::Mariner, Some("๐ ")),
(Type::MidnightBSD, Some("๐ ")),
(Type::Mint, Some("๐ฟ ")),
(Type::NetBSD, Some("๐ฉ ")),
(Type::NixOS, Some("โ๏ธ ")),
(Type::OpenBSD, Some("๐ก ")),
(Type::openSUSE, Some("๐ฆ ")),
(Type::OracleLinux, Some("๐ฆด ")),
(Type::Pop, Some("๐ญ ")),
(Type::Raspbian, Some("๐ ")),
(Type::Redhat, Some("๐ฉ ")),
(Type::RedHatEnterprise, Some("๐ฉ ")),
(Type::Redox, Some("๐งช ")),
(Type::Solus, Some("โต ")),
(Type::SUSE, Some("๐ฆ ")),
(Type::Ubuntu, Some("๐ฏ ")),
(Type::Unknown, Some("")),
(Type::Windows, Some("๐ช ")),
];
for (t, e) in type_expected_pairs {
assert_eq!(get_symbol(&config, &t), e);
}
}
#[test]
fn warn_on_os_info_update() {
#[warn(clippy::wildcard_enum_match_arm)]
let _ = |t: Type| match t {
Type::Alpine => "๐๏ธ ",
Type::Amazon => "๐ ",
Type::Android => "๐ค ",
Type::Arch => "๐๏ธ ",
Type::CentOS => "๐ ",
Type::Debian => "๐ ",
Type::DragonFly => "๐ ",
Type::Emscripten => "๐ ",
Type::EndeavourOS => "๐ ",
Type::Fedora => "๐ฉ ",
Type::FreeBSD => "๐ ",
Type::Garuda => "๐ฆ
",
Type::Gentoo => "๐๏ธ ",
Type::HardenedBSD => "๐ก๏ธ ",
Type::Illumos => "๐ฆ ",
Type::Linux => "๐ง ",
Type::Macos => "๐ ",
Type::Manjaro => "๐ฅญ ",
Type::Mariner => "๐ ",
Type::MidnightBSD => "๐ ",
Type::Mint => "๐ฟ ",
Type::NetBSD => "๐ฉ ",
Type::NixOS => "โ๏ธ ",
Type::OpenBSD => "๐ก ",
Type::openSUSE => "๐ฆ ",
Type::OracleLinux => "๐ฆด ",
Type::Pop => "๐ญ ",
Type::Raspbian => "๐ ",
Type::Redhat => "๐ฉ ",
Type::RedHatEnterprise => "๐ฉ ",
Type::Redox => "๐งช ",
Type::Solus => "โต ",
Type::SUSE => "๐ฆ ",
Type::Ubuntu => "๐ฏ ",
Type::Unknown => "โ ",
Type::Windows => "๐ช ",
_ => "",
};
}
}