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> { 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 { os.codename().map(String::from) } fn get_edition(os: &os_info::Info) -> Option { os.edition().map(String::from) } fn get_name(os: &os_info::Info) -> Option { Some(os.os_type().to_string()) } fn get_type(os: &os_info::Info) -> Option { // String from os_info::Type Some(format!("{:?}", os.os_type())) } fn get_version(os: &os_info::Info) -> Option { 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::default(); 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::Alpaquita => "๐Ÿ”” ", Type::Alpine => "๐Ÿ”๏ธ ", Type::Amazon => "๐Ÿ™‚ ", Type::Android => "๐Ÿค– ", Type::Arch | Type::Artix => "๐ŸŽ—๏ธ ", 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::Mabox => "๐Ÿ“ฆ ", Type::Macos => "๐ŸŽ ", Type::Manjaro => "๐Ÿฅญ ", Type::Mariner => "๐ŸŒŠ ", Type::MidnightBSD => "๐ŸŒ˜ ", Type::Mint => "๐ŸŒฟ ", Type::NetBSD => "๐Ÿšฉ ", Type::NixOS => "โ„๏ธ ", Type::OpenBSD => "๐Ÿก ", Type::OpenCloudOS => "โ˜๏ธ ", Type::openEuler => "๐Ÿฆ‰ ", Type::openSUSE => "๐ŸฆŽ ", Type::OracleLinux => "๐Ÿฆด ", Type::Pop => "๐Ÿญ ", Type::Raspbian => "๐Ÿ“ ", Type::Redhat => "๐ŸŽฉ ", Type::RedHatEnterprise => "๐ŸŽฉ ", Type::Redox => "๐Ÿงช ", Type::Solus => "โ›ต ", Type::SUSE => "๐ŸฆŽ ", Type::Ubuntu => "๐ŸŽฏ ", Type::Unknown => "โ“ ", Type::Windows => "๐ŸชŸ ", _ => "", }; } }