starship/src/modules/os.rs

374 lines
12 KiB
Rust

use super::{Context, Module, ModuleConfig};
use crate::configs::os::OSConfig;
use crate::formatter::StringFormatter;
/// Creates a module with the current operating system
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)
}
// Get the operating system symbol from user config, or else default config
// when user has not defined a symbol for the operating system.
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> {
// String from os_info::Type
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(os_info::Version::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)]
// This closure is the same as the default config symbols list.
// When this clippy test fails, a new default symbol should be added to
// `config/os.rs` to exhaustively match new possible `os_info::Type` cases.
// Affects:
// - crate::configs::os::OSConfig::default()
// - crate::modules::os::tests
// - docs/config/README.md/#Configuration/#OS/#Options
// - docs/config/README.md/#Configuration/#OS/#Example
// - docs/.vuepress/public/presets/toml/plain-text-symbols.toml
// - dosc/.vuepress/public/presets/toml/nerd-font-symbols.toml
// - .github/config-schema.json
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 => "๐ŸชŸ ",
_ => "",
};
}
}