From 3109943822a15b22faaa6cdfda17ca9554bcd800 Mon Sep 17 00:00:00 2001 From: exincore Date: Sun, 6 Nov 2022 14:37:58 -0700 Subject: [PATCH] feat: Add operating system module (#4109) * docs(os): Add os module documentation * docs(os): Add os to Default Prompt Format * chore(os): Update config file schema * feat(os): Add os entries and declarations * feat(os): Add os module and config * fix(os): Obey config.disabled * feat(os): make variables 'Unknown'-aware refactor(os): calculate variables in dedicated functions * test(os): Add os module tests * feat(os): make 'name' variable less 'Unknown'-aware * docs(os): Add Preset configurations docs(os): Use emoji as default * feat(os): Use emoji as default test(os): Use emoji as default * fix(os): Add spaces after emoji symbols * chore(os): Update config schema * feat(os): Remove `bitness` variable docs(os): Remove `bitness` variable test(os): Remove `bitness` test * feat(os): Add Cargo.toml upgrade caution for os_info * refactor(os): Clarify get_symbol function * docs(os): Mention supported operating systems and feature requests * docs(os): Mention os_info inacurracy * test(os): Remove `bitness` leftovers * refactor(os): use nu_ansi_term * refactor(os): add cfg_attr(schemars(deny_unknown_fields)) * chore(os): update config schema * docs(os): expose details block * feat(os): add garuda linux * chore(os): update config schema * feat(os): add case insensitivity * feat(os): add symbols `IndexMap` use `os_info::Type` instead of `String` * test(os): add clippy warn on new os_info::Type case * leave missing case to test github tests * test(os): re-add missing test case * style(os): fix formatting * docs(os): update to match os_info::Type serialization - docs(os): add missing garuda to config - test(os): mention docs updates in warn_on_os_info_update --- .github/config-schema.json | 112 ++++++ Cargo.toml | 1 + .../presets/toml/bracketed-segments.toml | 3 + .../presets/toml/nerd-font-symbols.toml | 38 ++ .../public/presets/toml/pastel-powerline.toml | 11 +- .../presets/toml/plain-text-symbols.toml | 38 ++ docs/config/README.md | 103 +++++ src/configs/mod.rs | 3 + src/configs/os.rs | 83 ++++ src/configs/starship_root.rs | 1 + src/module.rs | 1 + src/modules/mod.rs | 3 + src/modules/os.rs | 373 ++++++++++++++++++ 13 files changed, 769 insertions(+), 1 deletion(-) create mode 100644 src/configs/os.rs create mode 100644 src/modules/os.rs diff --git a/.github/config-schema.json b/.github/config-schema.json index 92ed18e7..06040bbc 100644 --- a/.github/config-schema.json +++ b/.github/config-schema.json @@ -1027,6 +1027,56 @@ } ] }, + "os": { + "default": { + "disabled": true, + "format": "[$symbol]($style)", + "style": "bold white", + "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": "๐Ÿก ", + "OracleLinux": "๐Ÿฆด ", + "Pop": "๐Ÿญ ", + "Raspbian": "๐Ÿ“ ", + "RedHatEnterprise": "๐ŸŽฉ ", + "Redhat": "๐ŸŽฉ ", + "Redox": "๐Ÿงช ", + "SUSE": "๐ŸฆŽ ", + "Solus": "โ›ต ", + "Ubuntu": "๐ŸŽฏ ", + "Unknown": "โ“ ", + "Windows": "๐ŸชŸ ", + "openSUSE": "๐ŸฆŽ " + } + }, + "allOf": [ + { + "$ref": "#/definitions/OSConfig" + } + ] + }, "package": { "default": { "disabled": false, @@ -3989,6 +4039,68 @@ }, "additionalProperties": false }, + "OSConfig": { + "type": "object", + "properties": { + "format": { + "default": "[$symbol]($style)", + "type": "string" + }, + "style": { + "default": "bold white", + "type": "string" + }, + "symbols": { + "default": { + "Alpine": "๐Ÿ”๏ธ ", + "Amazon": "๐Ÿ™‚ ", + "Android": "๐Ÿค– ", + "Arch": "๐ŸŽ—๏ธ ", + "CentOS": "๐Ÿ’  ", + "Debian": "๐ŸŒ€ ", + "DragonFly": "๐Ÿ‰ ", + "Emscripten": "๐Ÿ”— ", + "EndeavourOS": "๐Ÿš€ ", + "Fedora": "๐ŸŽฉ ", + "FreeBSD": "๐Ÿ˜ˆ ", + "Garuda": "๐Ÿฆ… ", + "Gentoo": "๐Ÿ—œ๏ธ ", + "HardenedBSD": "๐Ÿ›ก๏ธ ", + "Illumos": "๐Ÿฆ ", + "Linux": "๐Ÿง ", + "Macos": "๐ŸŽ ", + "Manjaro": "๐Ÿฅญ ", + "Mariner": "๐ŸŒŠ ", + "MidnightBSD": "๐ŸŒ˜ ", + "Mint": "๐ŸŒฟ ", + "NetBSD": "๐Ÿšฉ ", + "NixOS": "โ„๏ธ ", + "OpenBSD": "๐Ÿก ", + "OracleLinux": "๐Ÿฆด ", + "Pop": "๐Ÿญ ", + "Raspbian": "๐Ÿ“ ", + "RedHatEnterprise": "๐ŸŽฉ ", + "Redhat": "๐ŸŽฉ ", + "Redox": "๐Ÿงช ", + "SUSE": "๐ŸฆŽ ", + "Solus": "โ›ต ", + "Ubuntu": "๐ŸŽฏ ", + "Unknown": "โ“ ", + "Windows": "๐ŸชŸ ", + "openSUSE": "๐ŸฆŽ " + }, + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "disabled": { + "default": true, + "type": "boolean" + } + }, + "additionalProperties": false + }, "PackageConfig": { "type": "object", "properties": { diff --git a/Cargo.toml b/Cargo.toml index 40c7b6b8..d587edb2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,6 +60,7 @@ notify-rust = { version = "4.5.10", optional = true } nu-ansi-term = "0.46.0" once_cell = "1.16.0" open = "3.0.3" +# update os module config and tests when upgrading os_info os_info = "3.5.1" path-slash = "0.2.1" pest = "2.4.1" diff --git a/docs/.vuepress/public/presets/toml/bracketed-segments.toml b/docs/.vuepress/public/presets/toml/bracketed-segments.toml index cdd48cf9..7317375a 100644 --- a/docs/.vuepress/public/presets/toml/bracketed-segments.toml +++ b/docs/.vuepress/public/presets/toml/bracketed-segments.toml @@ -109,6 +109,9 @@ format = '\[[$symbol($version)]($style)\]' [openstack] format = '\[[$symbol$cloud(\($project\))]($style)\]' +[os] +format = '\[[$symbol]($style)\]' + [package] format = '\[[$symbol$version]($style)\]' diff --git a/docs/.vuepress/public/presets/toml/nerd-font-symbols.toml b/docs/.vuepress/public/presets/toml/nerd-font-symbols.toml index f8f2700b..c2c93536 100644 --- a/docs/.vuepress/public/presets/toml/nerd-font-symbols.toml +++ b/docs/.vuepress/public/presets/toml/nerd-font-symbols.toml @@ -64,6 +64,44 @@ symbol = "๏Œ“ " [nodejs] symbol = "๎œ˜ " +[os.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 = "๏œน " +openSUSE = "๏Œ” " +OracleLinux = "๏ ถ " +Pop = "๎Šฃ " +Raspbian = "๏Œ• " +Redhat = "๏Œ– " +RedHatEnterprise = "๏Œ– " +Redox = "๏”— " +Solus = "๏ดฑ " +SUSE = "๏Œ” " +Ubuntu = "๏Œ› " +Unknown = "๏ˆญ " +Windows = "๏กฑ " + [package] symbol = "๏ฃ– " diff --git a/docs/.vuepress/public/presets/toml/pastel-powerline.toml b/docs/.vuepress/public/presets/toml/pastel-powerline.toml index e2115c6c..6c240d06 100644 --- a/docs/.vuepress/public/presets/toml/pastel-powerline.toml +++ b/docs/.vuepress/public/presets/toml/pastel-powerline.toml @@ -1,5 +1,6 @@ format = """ [๎‚ถ](#9A348E)\ +$os\ $username\ [๎‚ฐ](bg:#DA627D fg:#9A348E)\ $directory\ @@ -28,12 +29,20 @@ $time\ # Disable the blank line at the start of the prompt # add_newline = false -# You can also replace your username with a neat symbol like ๏„  to save some space +# You can also replace your username with a neat symbol like ๏„  or disable this +# and use the os module below [username] show_always = true style_user = "bg:#9A348E" style_root = "bg:#9A348E" format = '[$user ]($style)' +disabled = false + +# An alternative to the username module which displays a symbol that +# represents the current operating system +[os] +style = "bg:#9A348E" +disabled = true # Disabled by default [directory] style = "bg:#DA627D" diff --git a/docs/.vuepress/public/presets/toml/plain-text-symbols.toml b/docs/.vuepress/public/presets/toml/plain-text-symbols.toml index bc555349..bf659198 100644 --- a/docs/.vuepress/public/presets/toml/plain-text-symbols.toml +++ b/docs/.vuepress/public/presets/toml/plain-text-symbols.toml @@ -103,6 +103,44 @@ symbol = "ml " [opa] symbol = "opa " +[os.symbols] +Alpine = "alp " +Amazon = "amz " +Android = "andr " +Arch = "rch " +CentOS = "cent " +Debian = "deb " +DragonFly = "dfbsd " +Emscripten = "emsc " +EndeavourOS = "ndev " +Fedora = "fed " +FreeBSD = "fbsd " +Garuda = "garu " +Gentoo = "gent " +HardenedBSD = "hbsd " +Illumos = "lum " +Linux = "lnx " +Macos = "mac " +Manjaro = "mjo " +Mariner = "mrn " +MidnightBSD = "mid " +Mint = "mint " +NetBSD = "nbsd " +NixOS = "nix " +OpenBSD = "obsd " +openSUSE = "osuse " +OracleLinux = "orac " +Pop = "pop " +Raspbian = "rasp " +Redhat = "rhl " +RedHatEnterprise = "rhel " +Redox = "redox " +Solus = "sol " +SUSE = "suse " +Ubuntu = "ubnt " +Unknown = "unk " +Windows = "win " + [package] symbol = "pkg " diff --git a/docs/config/README.md b/docs/config/README.md index e1473615..36da4b14 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -331,6 +331,7 @@ $jobs\ $battery\ $time\ $status\ +$os\ $container\ $shell\ $character""" @@ -2782,6 +2783,108 @@ style = 'bold yellow' symbol = 'โ˜๏ธ ' ``` +## OS + +The `os` module shows the current operating system. +OS information is detected via the [os_info](https://lib.rs/crates/os_info) crate. + +::: warning + +The [os_info](https://lib.rs/crates/os_info) crate used by this module is known to be inaccurate on some systems. + +::: + +::: tip + +This module is disabled by default. +To enable it, set `disabled` to `false` in your configuration file. + +::: + +### Options + +| Option | Default | Description | +| ---------- | --------------------- | ------------------------------------------------------ | +| `format` | `"[$symbol]($style)"` | The format for the module. | +| `style` | `"bold white"` | The style for the module. | +| `disabled` | `true` | Disables the `os` module. | +| `symbols` | | A table that maps each operating system to its symbol. | + +`symbols` allows you to define arbitrary symbols to display for each operating system type. +Operating system types not defined by your configuration use the default symbols table below. +All operating systems currently supported by the module are listed below. +If you would like an operating system to be added, feel free to open a [feature request](https://github.com/starship/starship/issues/new/choose). + +```toml +# This is the default symbols table. +[os.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 = "๐Ÿก " +openSUSE = "๐ŸฆŽ " +OracleLinux = "๐Ÿฆด " +Pop = "๐Ÿญ " +Raspbian = "๐Ÿ“ " +Redhat = "๐ŸŽฉ " +RedHatEnterprise = "๐ŸŽฉ " +Redox = "๐Ÿงช " +Solus = "โ›ต " +SUSE = "๐ŸฆŽ " +Ubuntu = "๐ŸŽฏ " +Unknown = "โ“ " +Windows = "๐ŸชŸ " +``` + +### Variables + +| Variable | Example | Description | +| -------- | ------------ | ------------------------------------------------------------------ | +| symbol | `๐ŸŽ—๏ธ` | The current operating system symbol from advanced option `symbols` | +| name | `Arch Linux` | The current operating system name | +| type | `Arch` | The current operating system type | +| codename | | The current operating system codename, if applicable | +| edition | | The current operating system edition, if applicable | +| version | | The current operating system version, if applicable | +| style\* | | Mirrors the value of option `style` | + +*: This variable can only be used as a part of a style string + +### Example + +```toml +# ~/.config/starship.toml + +[os] +format = "on [($name )]($style)" +style = "bold blue" +disabled = false + +[os.symbols] +Windows = "๎˜ช " +Arch = "Arch is the best! " +``` + ## Package Version The `package` module is shown when the current directory is the repository for a diff --git a/src/configs/mod.rs b/src/configs/mod.rs index 035b09e0..bfb5e95a 100644 --- a/src/configs/mod.rs +++ b/src/configs/mod.rs @@ -54,6 +54,7 @@ pub mod nodejs; pub mod ocaml; pub mod opa; pub mod openstack; +pub mod os; pub mod package; pub mod perl; pub mod php; @@ -203,6 +204,8 @@ pub struct FullConfig<'a> { #[serde(borrow)] openstack: openstack::OspConfig<'a>, #[serde(borrow)] + os: os::OSConfig<'a>, + #[serde(borrow)] package: package::PackageConfig<'a>, #[serde(borrow)] perl: perl::PerlConfig<'a>, diff --git a/src/configs/os.rs b/src/configs/os.rs new file mode 100644 index 00000000..73c84aba --- /dev/null +++ b/src/configs/os.rs @@ -0,0 +1,83 @@ +use indexmap::{indexmap, IndexMap}; +use os_info::Type; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Deserialize, Serialize)] +#[cfg_attr( + feature = "config-schema", + derive(schemars::JsonSchema), + schemars(deny_unknown_fields) +)] +#[serde(default)] +pub struct OSConfig<'a> { + pub format: &'a str, + pub style: &'a str, + pub symbols: IndexMap, + pub disabled: bool, +} + +impl<'a> OSConfig<'a> { + pub fn get_symbol(&self, key: &Type) -> Option<&'a str> { + self.symbols.get(key).cloned() + } +} + +impl<'a> Default for OSConfig<'a> { + fn default() -> Self { + OSConfig { + format: "[$symbol]($style)", + style: "bold white", + symbols: indexmap! { + 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 => "๐ŸชŸ ", + // Future symbols. + //aosc => "๏Œ ", + //artix => "๏„ค ", + //coreos => "๏Œ… ", + //devuan => "๏Œ‡ ", + //elementary => "๏Œ‰ ", + //mageia => "๏Œ ", + //mandriva => "๏Œ‘ ", + //sabayon => "๏Œ— ", + //slackware => "๏Œ˜ ", + //void => "๎Š™ ", + //solaris => "๏†… ", + }, + disabled: true, + } + } +} diff --git a/src/configs/starship_root.rs b/src/configs/starship_root.rs index 7456c3ca..f15a6fa5 100644 --- a/src/configs/starship_root.rs +++ b/src/configs/starship_root.rs @@ -108,6 +108,7 @@ pub const PROMPT_ORDER: &[&str] = &[ "time", "status", "container", + "os", "shell", "character", ]; diff --git a/src/module.rs b/src/module.rs index 871c2f9d..41d11398 100644 --- a/src/module.rs +++ b/src/module.rs @@ -62,6 +62,7 @@ pub const ALL_MODULES: &[&str] = &[ "ocaml", "opa", "openstack", + "os", "package", "perl", "php", diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 99952bd6..7a07b73c 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -51,6 +51,7 @@ mod nodejs; mod ocaml; mod opa; mod openstack; +mod os; mod package; mod perl; mod php; @@ -148,6 +149,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option> { "ocaml" => ocaml::module(context), "opa" => opa::module(context), "openstack" => openstack::module(context), + "os" => os::module(context), "package" => package::module(context), "perl" => perl::module(context), "php" => php::module(context), @@ -258,6 +260,7 @@ pub fn description(module: &str) -> &'static str { "ocaml" => "The currently installed version of OCaml", "opa" => "The currently installed version of Open Platform Agent", "openstack" => "The current OpenStack cloud and project", + "os" => "The current operating system", "package" => "The package version of the current directory's project", "perl" => "The currently installed version of Perl", "php" => "The currently installed version of PHP", diff --git a/src/modules/os.rs b/src/modules/os.rs new file mode 100644 index 00000000..aa4d9b93 --- /dev/null +++ b/src/modules/os.rs @@ -0,0 +1,373 @@ +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(|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)] + // 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 => "๐ŸชŸ ", + _ => "", + }; + } +}