style: pedantic refactoring (#6771)

---------

Co-authored-by: daniel.eades <daniel.eades@seebyte.com>
This commit is contained in:
danieleades
2025-08-17 15:51:04 +01:00
committed by GitHub
parent 6d717b20ae
commit 3760f29560
59 changed files with 391 additions and 421 deletions
+2 -2
View File
@@ -42,7 +42,7 @@ fn gen_presets_hook(mut file: &File) -> SdResult<()> {
writeln!( writeln!(
file, file,
r#" r"
use crate::print; use crate::print;
pub fn get_preset_list<'a>() -> &'a [print::Preset] {{ pub fn get_preset_list<'a>() -> &'a [print::Preset] {{
@@ -57,7 +57,7 @@ pub fn get_preset_content(name: &str) -> &[u8] {{
_ => unreachable!(), _ => unreachable!(),
}} }}
}} }}
"# "
)?; )?;
Ok(()) Ok(())
} }
+13 -17
View File
@@ -11,7 +11,7 @@ use serde::{
use std::borrow::Cow; use std::borrow::Cow;
use std::clone::Clone; use std::clone::Clone;
use std::collections::HashMap; use std::collections::HashMap;
use std::ffi::OsString; use std::ffi::OsStr;
use std::io::ErrorKind; use std::io::ErrorKind;
use toml::Value; use toml::Value;
@@ -38,7 +38,7 @@ where
} }
} }
/// Helper function that will call `ModuleConfig::from_config(config) if config is Some, /// Helper function that will call `ModuleConfig::from_config(config)` if config is Some,
/// or `ModuleConfig::default()` if config is None. /// or `ModuleConfig::default()` if config is None.
fn try_load<V: Into<ValueRef<'a>>>(config: Option<V>) -> Self { fn try_load<V: Into<ValueRef<'a>>>(config: Option<V>) -> Self {
config.map(Into::into).map(Self::load).unwrap_or_default() config.map(Into::into).map(Self::load).unwrap_or_default()
@@ -124,7 +124,7 @@ pub struct StarshipConfig {
impl StarshipConfig { impl StarshipConfig {
/// Initialize the Config struct /// Initialize the Config struct
pub fn initialize(config_file_path: &Option<OsString>) -> Self { pub fn initialize(config_file_path: Option<&OsStr>) -> Self {
Self::config_from_file(config_file_path) Self::config_from_file(config_file_path)
.map(|config| Self { .map(|config| Self {
config: Some(config), config: Some(config),
@@ -133,7 +133,7 @@ impl StarshipConfig {
} }
/// Create a config from a starship configuration file /// Create a config from a starship configuration file
fn config_from_file(config_file_path: &Option<OsString>) -> Option<toml::Table> { fn config_from_file(config_file_path: Option<&OsStr>) -> Option<toml::Table> {
let toml_content = Self::read_config_content_as_str(config_file_path)?; let toml_content = Self::read_config_content_as_str(config_file_path)?;
match toml::from_str(&toml_content) { match toml::from_str(&toml_content) {
@@ -148,7 +148,7 @@ impl StarshipConfig {
} }
} }
pub fn read_config_content_as_str(config_file_path: &Option<OsString>) -> Option<String> { pub fn read_config_content_as_str(config_file_path: Option<&OsStr>) -> Option<String> {
if config_file_path.is_none() { if config_file_path.is_none() {
log::debug!( log::debug!(
"Unable to determine `config_file_path`. Perhaps `utils::home_dir` is not defined on your platform?" "Unable to determine `config_file_path`. Perhaps `utils::home_dir` is not defined on your platform?"
@@ -201,12 +201,10 @@ impl StarshipConfig {
// Assumes all keys except the last in path has a table // Assumes all keys except the last in path has a table
for option in table_options { for option in table_options {
match prev_table.get(*option) { if let Some(value) = prev_table.get(*option) {
Some(value) => match value.as_table() { if let Some(value) = value.as_table() {
Some(value) => {
prev_table = value; prev_table = value;
} } else {
None => {
log::trace!( log::trace!(
"No config found for \"{}\": \"{}\" is not a table", "No config found for \"{}\": \"{}\" is not a table",
path.join("."), path.join("."),
@@ -214,17 +212,15 @@ impl StarshipConfig {
); );
return None; return None;
} }
}, } else if prev_table.contains_key(*option) {
None => {
log::trace!( log::trace!(
"No config found for \"{}\": Option \"{}\" not found", "No config found for \"{}\": \"{}\" is not a table",
path.join("."), path.join("."),
&option &option
); );
return None; return None;
} }
} }
}
let last_option = path.last().unwrap(); let last_option = path.last().unwrap();
let value = prev_table.get(*last_option); let value = prev_table.get(*last_option);
@@ -234,7 +230,7 @@ impl StarshipConfig {
path.join("."), path.join("."),
&last_option &last_option
); );
}; }
value value
} }
@@ -1021,7 +1017,7 @@ mod tests {
assert_eq!( assert_eq!(
parse_color_string("green", Some(&palette)), parse_color_string("green", Some(&palette)),
Some(Color::Green) Some(Color::Green)
) );
} }
#[test] #[test]
@@ -1064,7 +1060,7 @@ mod tests {
fn read_config_no_config_file_path_provided() { fn read_config_no_config_file_path_provided() {
assert_eq!( assert_eq!(
None, None,
StarshipConfig::read_config_content_as_str(&None), StarshipConfig::read_config_content_as_str(None),
"if the platform doesn't have utils::home_dir(), it should return None" "if the platform doesn't have utils::home_dir(), it should return None"
); );
} }
+2 -2
View File
@@ -17,8 +17,8 @@ pub struct OSConfig<'a> {
} }
impl<'a> OSConfig<'a> { impl<'a> OSConfig<'a> {
pub fn get_symbol(&self, key: &Type) -> Option<&'a str> { pub fn get_symbol(&self, key: Type) -> Option<&'a str> {
self.symbols.get(key).copied() self.symbols.get(&key).copied()
} }
} }
+13 -12
View File
@@ -224,14 +224,14 @@ fn handle_toggle_configuration(doc: &mut DocumentMut, name: &str, key: &str) ->
} }
pub fn get_configuration(context: &Context) -> toml::Table { pub fn get_configuration(context: &Context) -> toml::Table {
let starship_config = StarshipConfig::initialize(&context.get_config_path_os()); let starship_config = StarshipConfig::initialize(context.get_config_path_os().as_deref());
starship_config.config.unwrap_or_default() starship_config.config.unwrap_or_default()
} }
pub fn get_configuration_edit(context: &Context) -> DocumentMut { pub fn get_configuration_edit(context: &Context) -> DocumentMut {
let config_file_path = context.get_config_path_os(); let config_file_path = context.get_config_path_os();
let toml_content = StarshipConfig::read_config_content_as_str(&config_file_path); let toml_content = StarshipConfig::read_config_content_as_str(config_file_path.as_deref());
toml_content toml_content
.unwrap_or_default() .unwrap_or_default()
@@ -313,13 +313,13 @@ fn get_editor_internal(visual: Option<String>, editor: Option<String>) -> String
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::{fs::create_dir, io}; use std::{fs::create_dir, io, path::PathBuf};
use tempfile::TempDir; use tempfile::TempDir;
use toml_edit::Item; use toml_edit::Item;
use crate::{ use crate::{
context::{Shell, Target}, context::{Properties, Shell, Target},
context_env::Env, context_env::Env,
}; };
@@ -376,13 +376,13 @@ mod tests {
#[test] #[test]
fn no_panic_when_editor_unparsable() { fn no_panic_when_editor_unparsable() {
let outcome = edit_configuration(&Default::default(), Some("\"vim")); let outcome = edit_configuration(&Context::default(), Some("\"vim"));
assert!(outcome.is_err()); assert!(outcome.is_err());
} }
#[test] #[test]
fn no_panic_when_editor_not_found() { fn no_panic_when_editor_not_found() {
let outcome = edit_configuration(&Default::default(), Some("this_editor_does_not_exist")); let outcome = edit_configuration(&Context::default(), Some("this_editor_does_not_exist"));
assert!(outcome.is_err()); assert!(outcome.is_err());
} }
@@ -464,7 +464,7 @@ mod tests {
"\n" "\n"
); );
assert_eq!(doc.to_string(), new_config) assert_eq!(doc.to_string(), new_config);
} }
#[test] #[test]
@@ -529,7 +529,7 @@ mod tests {
"\n" "\n"
); );
assert_eq!(doc.to_string(), new_config) assert_eq!(doc.to_string(), new_config);
} }
#[test] #[test]
@@ -578,7 +578,7 @@ mod tests {
doc["a"]["b"]["c"]["d"]["e"]["f"]["g"]["h"] doc["a"]["b"]["c"]["d"]["e"]["f"]["g"]["h"]
.as_bool() .as_bool()
.unwrap() .unwrap()
) );
} }
#[test] #[test]
@@ -629,6 +629,7 @@ mod tests {
Ok(()) Ok(())
} }
#[derive(Clone, Copy)]
enum StarshipConfigEnvScenario { enum StarshipConfigEnvScenario {
NotSpecified, NotSpecified,
NonExistingFile, NonExistingFile,
@@ -683,11 +684,11 @@ mod tests {
); );
Ok(Context::new_with_shell_and_path( Ok(Context::new_with_shell_and_path(
Default::default(), Properties::default(),
Shell::Unknown, Shell::Unknown,
Target::Main, Target::Main,
Default::default(), PathBuf::default(),
Default::default(), PathBuf::default(),
env, env,
)) ))
} }
+8 -8
View File
@@ -128,7 +128,7 @@ impl<'a> Context<'a> {
logical_path: PathBuf, logical_path: PathBuf,
env: Env<'a>, env: Env<'a>,
) -> Self { ) -> Self {
let config = StarshipConfig::initialize(&get_config_path_os(&env)); let config = StarshipConfig::initialize(get_config_path_os(&env).as_deref());
// If the vector is zero-length, we should pretend that we didn't get a // If the vector is zero-length, we should pretend that we didn't get a
// pipestatus at all (since this is the input `--pipestatus=""`) // pipestatus at all (since this is the input `--pipestatus=""`)
@@ -433,7 +433,7 @@ impl<'a> Context<'a> {
} }
/// Attempt to execute several commands with `exec_cmd`, return the results of the first that works /// Attempt to execute several commands with `exec_cmd`, return the results of the first that works
pub fn exec_cmds_return_first(&self, commands: Vec<Vec<&str>>) -> Option<CommandOutput> { pub fn exec_cmds_return_first(&self, commands: &[Vec<&str>]) -> Option<CommandOutput> {
commands commands
.iter() .iter()
.find_map(|attempt| self.exec_cmd(attempt[0], &attempt[1..])) .find_map(|attempt| self.exec_cmd(attempt[0], &attempt[1..]))
@@ -1153,12 +1153,12 @@ mod tests {
// Mock navigation into the symlink path // Mock navigation into the symlink path
let test_path = path_symlink.join("yyy"); let test_path = path_symlink.join("yyy");
let context = Context::new_with_shell_and_path( let context = Context::new_with_shell_and_path(
Default::default(), Properties::default(),
Shell::Unknown, Shell::Unknown,
Target::Main, Target::Main,
test_path.clone(), test_path.clone(),
test_path.clone(), test_path.clone(),
Default::default(), Env::default(),
); );
assert_ne!(context.current_dir, context.logical_dir); assert_ne!(context.current_dir, context.logical_dir);
@@ -1178,12 +1178,12 @@ mod tests {
// Mock navigation to a directory which does not exist on disk // Mock navigation to a directory which does not exist on disk
let test_path = Path::new("/path_which_does_not_exist").to_path_buf(); let test_path = Path::new("/path_which_does_not_exist").to_path_buf();
let context = Context::new_with_shell_and_path( let context = Context::new_with_shell_and_path(
Default::default(), Properties::default(),
Shell::Unknown, Shell::Unknown,
Target::Main, Target::Main,
test_path.clone(), test_path.clone(),
test_path.clone(), test_path.clone(),
Default::default(), Env::default(),
); );
let expected_current_dir = &test_path; let expected_current_dir = &test_path;
@@ -1200,12 +1200,12 @@ mod tests {
// Mock navigation to a directory which does not exist on disk // Mock navigation to a directory which does not exist on disk
let test_path = Path::new("~/path_which_does_not_exist").to_path_buf(); let test_path = Path::new("~/path_which_does_not_exist").to_path_buf();
let context = Context::new_with_shell_and_path( let context = Context::new_with_shell_and_path(
Default::default(), Properties::default(),
Shell::Unknown, Shell::Unknown,
Target::Main, Target::Main,
test_path.clone(), test_path.clone(),
test_path.clone(), test_path.clone(),
Default::default(), Env::default(),
); );
let expected_current_dir = home_dir() let expected_current_dir = home_dir()
+6 -6
View File
@@ -158,25 +158,25 @@ pub fn init_stub(shell_name: &str) -> io::Result<()> {
"zsh" => print_script(ZSH_INIT, &starship.sprint_posix()?), "zsh" => print_script(ZSH_INIT, &starship.sprint_posix()?),
"fish" => print!( "fish" => print!(
// Fish does process substitution with pipes and psub instead of bash syntax // Fish does process substitution with pipes and psub instead of bash syntax
r#"source ({} init fish --print-full-init | psub)"#, r"source ({} init fish --print-full-init | psub)",
starship.sprint_posix()? starship.sprint_posix()?
), ),
"powershell" => print!( "powershell" => print!(
r#"Invoke-Expression (& {} init powershell --print-full-init | Out-String)"#, r"Invoke-Expression (& {} init powershell --print-full-init | Out-String)",
starship.sprint_pwsh()? starship.sprint_pwsh()?
), ),
"ion" => print!("eval $({} init ion --print-full-init)", starship.sprint()?), "ion" => print!("eval $({} init ion --print-full-init)", starship.sprint()?),
"elvish" => print!( "elvish" => print!(
r#"eval ({} init elvish --print-full-init | slurp)"#, r"eval ({} init elvish --print-full-init | slurp)",
starship.sprint()? starship.sprint()?
), ),
"tcsh" => print!( "tcsh" => print!(
r#"eval `({} init tcsh --print-full-init)`"#, r"eval `({} init tcsh --print-full-init)`",
starship.sprint_posix()? starship.sprint_posix()?
), ),
"nu" => print_script(NU_INIT, &StarshipPath::init()?.sprint()?), "nu" => print_script(NU_INIT, &StarshipPath::init()?.sprint()?),
"xonsh" => print!( "xonsh" => print!(
r#"execx($({} init xonsh --print-full-init))"#, r"execx($({} init xonsh --print-full-init))",
starship.sprint_posix()? starship.sprint_posix()?
), ),
"cmd" => print_script(CMDEXE_INIT, &StarshipPath::init()?.sprint_cmdexe()?), "cmd" => print_script(CMDEXE_INIT, &StarshipPath::init()?.sprint_cmdexe()?),
@@ -198,7 +198,7 @@ pub fn init_stub(shell_name: &str) -> io::Result<()> {
Please open an issue in the starship repo if you would like to \ Please open an issue in the starship repo if you would like to \
see support for {shell_basename}:\n\ see support for {shell_basename}:\n\
https://github.com/starship/starship/issues/new\n" https://github.com/starship/starship/issues/new\n"
) );
} }
}; };
Ok(()) Ok(())
+1 -1
View File
@@ -86,7 +86,7 @@ impl Default for StarshipLogger {
let log_dir = get_log_dir(); let log_dir = get_log_dir();
if let Err(err) = fs::create_dir_all(&log_dir) { if let Err(err) = fs::create_dir_all(&log_dir) {
eprintln!("Unable to create log dir {log_dir:?}: {err:?}!") eprintln!("Unable to create log dir {log_dir:?}: {err:?}!");
}; };
let session_log_file = log_dir.join(format!( let session_log_file = log_dir.join(format!(
"session_{}.log", "session_{}.log",
+5 -4
View File
@@ -10,7 +10,7 @@ use clap_complete::generate;
use rand::Rng; use rand::Rng;
use starship::context::{Context, Properties, Target}; use starship::context::{Context, Properties, Target};
use starship::module::ALL_MODULES; use starship::module::ALL_MODULES;
use starship::*; use starship::{bug_report, configure, init, logger, num_rayon_threads, print, shadow};
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
#[clap( #[clap(
@@ -26,7 +26,7 @@ struct Cli {
command: Commands, command: Commands,
} }
#[derive(clap::Parser, ValueEnum, Debug, Clone, PartialEq, Eq)] #[derive(clap::Parser, ValueEnum, Debug, Clone, Copy, PartialEq, Eq)]
enum CompletionShell { enum CompletionShell {
Bash, Bash,
Elvish, Elvish,
@@ -42,7 +42,7 @@ fn generate_shell(shell: impl clap_complete::Generator) {
&mut Cli::command(), &mut Cli::command(),
"starship", "starship",
&mut io::stdout().lock(), &mut io::stdout().lock(),
) );
} }
fn generate_completions(shell: CompletionShell) { fn generate_completions(shell: CompletionShell) {
@@ -173,10 +173,11 @@ fn main() {
let exit_code = if is_info_only { let exit_code = if is_info_only {
0 0
} else { } else {
use io::Write;
// print the arguments // print the arguments
// avoid panicking in case of stderr closing // avoid panicking in case of stderr closing
let mut stderr = io::stderr(); let mut stderr = io::stderr();
use io::Write;
let _ = writeln!( let _ = writeln!(
stderr, stderr,
"\nNOTE:\n passed arguments: {:?}", "\nNOTE:\n passed arguments: {:?}",
+9 -9
View File
@@ -159,7 +159,7 @@ fn get_credentials_duration(
let cache_key = crate::utils::encode_to_hex(&Sha1::digest(start_url.as_bytes())); let cache_key = crate::utils::encode_to_hex(&Sha1::digest(start_url.as_bytes()));
// https://github.com/aws/aws-cli/blob/b3421dcdd443db95999364e94266c0337b45cc43/awscli/customizations/sso/utils.py#L89 // https://github.com/aws/aws-cli/blob/b3421dcdd443db95999364e94266c0337b45cc43/awscli/customizations/sso/utils.py#L89
let mut sso_cred_path = context.get_home()?; let mut sso_cred_path = context.get_home()?;
sso_cred_path.push(format!(".aws/sso/cache/{}.json", cache_key)); sso_cred_path.push(format!(".aws/sso/cache/{cache_key}.json"));
let sso_cred_json: json::Value = let sso_cred_json: json::Value =
json::from_str(&crate::utils::read_file(&sso_cred_path).ok()?).ok()?; json::from_str(&crate::utils::read_file(&sso_cred_path).ok()?).ok()?;
let expires_at = sso_cred_json.get("expiresAt")?.as_str(); let expires_at = sso_cred_json.get("expiresAt")?.as_str();
@@ -719,7 +719,7 @@ credential_process = /opt/bin/awscreds-retriever
use chrono::{DateTime, SecondsFormat, Utc}; use chrono::{DateTime, SecondsFormat, Utc};
let expiration_env_vars = ["AWS_SESSION_EXPIRATION", "AWS_CREDENTIAL_EXPIRATION"]; let expiration_env_vars = ["AWS_SESSION_EXPIRATION", "AWS_CREDENTIAL_EXPIRATION"];
expiration_env_vars.iter().for_each(|env_var| { for env_var in expiration_env_vars {
let now_plus_half_hour: DateTime<Utc> = let now_plus_half_hour: DateTime<Utc> =
DateTime::from_timestamp(chrono::Local::now().timestamp() + 1800, 0).unwrap(); DateTime::from_timestamp(chrono::Local::now().timestamp() + 1800, 0).unwrap();
@@ -747,24 +747,24 @@ credential_process = /opt/bin/awscreds-retriever
possible_values.contains(&actual), possible_values.contains(&actual),
"time is not in range: {actual:?}" "time is not in range: {actual:?}"
); );
}); }
} }
#[test] #[test]
fn expiration_date_set_from_file() -> io::Result<()> { fn expiration_date_set_from_file() -> io::Result<()> {
use chrono::{DateTime, Utc};
let dir = tempfile::tempdir()?; let dir = tempfile::tempdir()?;
let credentials_path = dir.path().join("credentials"); let credentials_path = dir.path().join("credentials");
let mut file = File::create(&credentials_path)?; let mut file = File::create(&credentials_path)?;
use chrono::{DateTime, Utc};
let now_plus_half_hour: DateTime<Utc> = let now_plus_half_hour: DateTime<Utc> =
DateTime::from_timestamp(chrono::Local::now().timestamp() + 1800, 0).unwrap(); DateTime::from_timestamp(chrono::Local::now().timestamp() + 1800, 0).unwrap();
let expiration_date = now_plus_half_hour.to_rfc3339_opts(chrono::SecondsFormat::Secs, true); let expiration_date = now_plus_half_hour.to_rfc3339_opts(chrono::SecondsFormat::Secs, true);
let expiration_keys = ["expiration", "x_security_token_expires"]; let expiration_keys = ["expiration", "x_security_token_expires"];
expiration_keys.iter().for_each(|key| { for key in expiration_keys {
file.write_all( file.write_all(
format!( format!(
"[astronauts] "[astronauts]
@@ -778,7 +778,7 @@ aws_secret_access_key=dummy
.unwrap(); .unwrap();
let credentials_env_vars = ["AWS_SHARED_CREDENTIALS_FILE", "AWS_CREDENTIALS_FILE"]; let credentials_env_vars = ["AWS_SHARED_CREDENTIALS_FILE", "AWS_CREDENTIALS_FILE"];
credentials_env_vars.iter().for_each(|env_var| { for env_var in credentials_env_vars {
let actual = ModuleRenderer::new("aws") let actual = ModuleRenderer::new("aws")
.env("AWS_PROFILE", "astronauts") .env("AWS_PROFILE", "astronauts")
.env("AWS_REGION", "ap-northeast-2") .env("AWS_REGION", "ap-northeast-2")
@@ -802,8 +802,8 @@ aws_secret_access_key=dummy
possible_values.contains(&actual), possible_values.contains(&actual),
"time is not in range: {actual:?}" "time is not in range: {actual:?}"
); );
}); }
}); }
dir.close() dir.close()
} }
+5 -6
View File
@@ -34,7 +34,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
if config.disabled { if config.disabled {
return None; return None;
}; }
let subscription: Option<Subscription> = get_azure_profile_info(context); let subscription: Option<Subscription> = get_azure_profile_info(context);
@@ -126,7 +126,7 @@ mod tests {
fn generate_test_config(dir: &TempDir, azure_profile_contents: &str) -> io::Result<()> { fn generate_test_config(dir: &TempDir, azure_profile_contents: &str) -> io::Result<()> {
save_string_to_file( save_string_to_file(
dir, dir,
azure_profile_contents.to_string(), azure_profile_contents,
String::from("azureProfile.json"), String::from("azureProfile.json"),
)?; )?;
@@ -737,7 +737,7 @@ mod tests {
bom_str.push_str(json_str); bom_str.push_str(json_str);
let dir_path_no_bom = save_string_to_file(&dir, bom_str, String::from("bom.json"))?; let dir_path_no_bom = save_string_to_file(&dir, &bom_str, String::from("bom.json"))?;
let sanitized_json = load_azure_profile(&dir_path_no_bom).unwrap(); let sanitized_json = load_azure_profile(&dir_path_no_bom).unwrap();
assert_eq!( assert_eq!(
@@ -755,8 +755,7 @@ mod tests {
let json_str = let json_str =
r#"{"installationId": "3deacd2a-b9db-77e1-aa42-23e2f8dfffc3", "subscriptions": []}"#; r#"{"installationId": "3deacd2a-b9db-77e1-aa42-23e2f8dfffc3", "subscriptions": []}"#;
let dir_path_no_bom = let dir_path_no_bom = save_string_to_file(&dir, json_str, String::from("bom.json"))?;
save_string_to_file(&dir, json_str.to_string(), String::from("bom.json"))?;
let sanitized_json = load_azure_profile(&dir_path_no_bom).unwrap(); let sanitized_json = load_azure_profile(&dir_path_no_bom).unwrap();
assert_eq!( assert_eq!(
@@ -783,7 +782,7 @@ mod tests {
fn save_string_to_file( fn save_string_to_file(
dir: &TempDir, dir: &TempDir,
contents: String, contents: &str,
file_name: String, file_name: String,
) -> Result<PathBuf, io::Error> { ) -> Result<PathBuf, io::Error> {
let bom_file_path = dir.path().join(file_name); let bom_file_path = dir.path().join(file_name);
+3 -3
View File
@@ -70,15 +70,15 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
fn get_battery_status(context: &Context) -> Option<BatteryStatus> { fn get_battery_status(context: &Context) -> Option<BatteryStatus> {
let battery_info = context.battery_info_provider.get_battery_info()?; let battery_info = context.battery_info_provider.get_battery_info()?;
if battery_info.energy_full != 0.0 { if battery_info.energy_full == 0.0 {
None
} else {
let battery = BatteryStatus { let battery = BatteryStatus {
percentage: battery_info.energy / battery_info.energy_full * 100.0, percentage: battery_info.energy / battery_info.energy_full * 100.0,
state: battery_info.state, state: battery_info.state,
}; };
log::debug!("Battery status: {battery:?}"); log::debug!("Battery status: {battery:?}");
Some(battery) Some(battery)
} else {
None
} }
} }
+2 -2
View File
@@ -61,10 +61,10 @@ fn get_bun_version(context: &Context) -> Option<String> {
context context
.exec_cmd("bun", &["--version"]) .exec_cmd("bun", &["--version"])
.map(get_command_string_output) .map(get_command_string_output)
.map(parse_bun_version) .map(|s| parse_bun_version(&s))
} }
fn parse_bun_version(bun_version: String) -> String { fn parse_bun_version(bun_version: &str) -> String {
bun_version.trim_end().to_string() bun_version.trim_end().to_string()
} }
+2 -1
View File
@@ -13,6 +13,7 @@ use std::borrow::Cow;
use std::ops::Deref; use std::ops::Deref;
use std::sync::LazyLock; use std::sync::LazyLock;
#[derive(Clone, Copy)]
pub enum Lang { pub enum Lang {
C, C,
Cpp, Cpp,
@@ -36,7 +37,7 @@ fn parse_module<T>(
compilers: [(&str, &str); 2], compilers: [(&str, &str); 2],
) -> Result<Vec<Segment>, crate::formatter::string_formatter::StringFormatterError> { ) -> Result<Vec<Segment>, crate::formatter::string_formatter::StringFormatterError> {
StringFormatter::new(config.format).and_then(|formatter| { StringFormatter::new(config.format).and_then(|formatter| {
let cc_compiler_info = LazyLock::new(|| context.exec_cmds_return_first(config.commands)); let cc_compiler_info = LazyLock::new(|| context.exec_cmds_return_first(&config.commands));
formatter formatter
.map_meta(|var, _| match var { .map_meta(|var, _| match var {
+4 -4
View File
@@ -168,10 +168,10 @@ mod tests {
// The value that should be rendered by the module. // The value that should be rendered by the module.
let expected = Some(format!( let expected = Some(format!(
"{} ", "{} ",
Color::Red Color::Red.bold().dimmed().paint(format!(
.bold() "⬢ [{}]",
.dimmed() name.unwrap_or_else(|| image.unwrap_or("podman"))
.paint(format!("⬢ [{}]", name.unwrap_or(image.unwrap_or("podman")))) ))
)); ));
Ok((actual, expected)) Ok((actual, expected))
+3 -4
View File
@@ -45,16 +45,15 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
.into_iter() .into_iter()
.find_map(|env| context.get_env(env)); .find_map(|env| context.get_env(env));
let ctx = match docker_context_env { let ctx = if let Some(data) = docker_context_env {
Some(data) => data, data
_ => { } else {
if !docker_config.exists() { if !docker_config.exists() {
return None; return None;
} }
let json = utils::read_file(docker_config).ok()?; let json = utils::read_file(docker_config).ok()?;
let parsed_json: serde_json::Value = serde_json::from_str(&json).ok()?; let parsed_json: serde_json::Value = serde_json::from_str(&json).ok()?;
parsed_json.get("currentContext")?.as_str()?.to_owned() parsed_json.get("currentContext")?.as_str()?.to_owned()
}
}; };
let default_contexts = ["default", "desktop-linux"]; let default_contexts = ["default", "desktop-linux"];
+3 -6
View File
@@ -282,7 +282,7 @@ fn get_dotnet_file_type(path: &Path) -> Option<FileType> {
Some("csproj" | "fsproj" | "xproj") => return Some(FileType::ProjectFile), Some("csproj" | "fsproj" | "xproj") => return Some(FileType::ProjectFile),
Some("props" | "targets") => return Some(FileType::MsBuildFile), Some("props" | "targets") => return Some(FileType::MsBuildFile),
_ => (), _ => (),
}; }
None None
} }
@@ -297,8 +297,7 @@ fn get_version_from_cli(context: &Context) -> Option<String> {
} }
fn get_latest_sdk_from_cli(context: &Context) -> Option<String> { fn get_latest_sdk_from_cli(context: &Context) -> Option<String> {
match context.exec_cmd("dotnet", &["--list-sdks"]) { if let Some(sdks_output) = context.exec_cmd("dotnet", &["--list-sdks"]) {
Some(sdks_output) => {
fn parse_failed<T>() -> Option<T> { fn parse_failed<T>() -> Option<T> {
log::warn!("Unable to parse the output from `dotnet --list-sdks`."); log::warn!("Unable to parse the output from `dotnet --list-sdks`.");
None None
@@ -319,8 +318,7 @@ fn get_latest_sdk_from_cli(context: &Context) -> Option<String> {
} else { } else {
parse_failed() parse_failed()
} }
} } else {
None => {
// Older versions of the dotnet cli do not support the --list-sdks command // Older versions of the dotnet cli do not support the --list-sdks command
// So, if the status code indicates failure, fall back to `dotnet --version` // So, if the status code indicates failure, fall back to `dotnet --version`
log::debug!( log::debug!(
@@ -329,7 +327,6 @@ fn get_latest_sdk_from_cli(context: &Context) -> Option<String> {
); );
get_version_from_cli(context) get_version_from_cli(context)
} }
}
} }
struct DotNetFile { struct DotNetFile {
+1 -1
View File
@@ -35,7 +35,7 @@ pub fn module<'a>(name: Option<&str>, context: &'a Context) -> Option<Module<'a>
let mut module = Module::new(mod_name, config.description, None); let mut module = Module::new(mod_name, config.description, None);
if config.disabled { if config.disabled {
return None; return None;
}; }
let variable_name = config.variable.or(name)?; let variable_name = config.variable.or(name)?;
+2 -2
View File
@@ -15,7 +15,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
// before it was only checking against whatever is in the config starship.toml // before it was only checking against whatever is in the config starship.toml
if config.disabled { if config.disabled {
return None; return None;
}; }
let checkout_db = if cfg!(windows) { let checkout_db = if cfg!(windows) {
"_FOSSIL_" "_FOSSIL_"
@@ -205,7 +205,7 @@ mod tests {
} }
Expect::Symbol(symbol) => expect_symbol = symbol, Expect::Symbol(symbol) => expect_symbol = symbol,
Expect::TruncationSymbol(truncation_symbol) => { Expect::TruncationSymbol(truncation_symbol) => {
expect_truncation_symbol = truncation_symbol expect_truncation_symbol = truncation_symbol;
} }
Expect::NoTruncation => expect_truncation_symbol = "", Expect::NoTruncation => expect_truncation_symbol = "",
Expect::BranchName(branch_name) => expect_branch_name = branch_name, Expect::BranchName(branch_name) => expect_branch_name = branch_name,
+1 -1
View File
@@ -15,7 +15,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
// before it was only checking against whatever is in the config starship.toml // before it was only checking against whatever is in the config starship.toml
if config.disabled { if config.disabled {
return None; return None;
}; }
let checkout_db = if cfg!(windows) { let checkout_db = if cfg!(windows) {
"_FOSSIL_" "_FOSSIL_"
+6 -5
View File
@@ -23,7 +23,7 @@ impl<'a> GcloudContext {
Self { Self {
config_name: config_name.to_string(), config_name: config_name.to_string(),
config_path: PathBuf::from(config_path), config_path: PathBuf::from(config_path),
config: Default::default(), config: OnceLock::default(),
} }
} }
@@ -73,10 +73,11 @@ fn get_config_dir(context: &Context) -> Option<PathBuf> {
fn get_active_config(context: &Context, config_dir: &Path) -> Option<String> { fn get_active_config(context: &Context, config_dir: &Path) -> Option<String> {
context.get_env("CLOUDSDK_ACTIVE_CONFIG_NAME").or_else(|| { context.get_env("CLOUDSDK_ACTIVE_CONFIG_NAME").or_else(|| {
let path = config_dir.join("active_config"); let path = config_dir.join("active_config");
match utils::read_file(path) { utils::read_file(path)
Ok(data) => data.lines().next().map(String::from), .ok()?
Err(_) => None, .lines()
} .next()
.map(String::from)
}) })
} }
+4 -4
View File
@@ -45,11 +45,11 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
let mut remote_name_graphemes: Vec<&str> = Vec::new(); let mut remote_name_graphemes: Vec<&str> = Vec::new();
if let Some(remote) = repo.remote.as_ref() { if let Some(remote) = repo.remote.as_ref() {
if let Some(branch) = &remote.branch { if let Some(branch) = &remote.branch {
remote_branch_graphemes = branch.graphemes(true).collect() remote_branch_graphemes = branch.graphemes(true).collect();
}; }
if let Some(name) = &remote.name { if let Some(name) = &remote.name {
remote_name_graphemes = name.graphemes(true).collect() remote_name_graphemes = name.graphemes(true).collect();
}; }
} }
// Truncate fields if need be // Truncate fields if need be
+1 -1
View File
@@ -19,7 +19,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
let is_detached = git_head.is_detached(); let is_detached = git_head.is_detached();
if config.only_detached && !is_detached { if config.only_detached && !is_detached {
return None; return None;
}; }
let parsed = StringFormatter::new(config.format).and_then(|formatter| { let parsed = StringFormatter::new(config.format).and_then(|formatter| {
formatter formatter
+12 -8
View File
@@ -21,7 +21,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
// before it was only checking against whatever is in the config starship.toml // before it was only checking against whatever is in the config starship.toml
if config.disabled { if config.disabled {
return None; return None;
}; }
let repo = context.get_repo().ok()?; let repo = context.get_repo().ok()?;
let gix_repo = repo.open(); let gix_repo = repo.open();
@@ -58,7 +58,10 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
gix_repo.write_blob([]).ok()?; /* create empty blob */ gix_repo.write_blob([]).ok()?; /* create empty blob */
let tree_index_cache = prevent_external_diff( let tree_index_cache = prevent_external_diff(
gix_repo gix_repo
.diff_resource_cache(gix::diff::blob::pipeline::Mode::ToGit, Default::default()) .diff_resource_cache(
gix::diff::blob::pipeline::Mode::ToGit,
WorktreeRoots::default(),
)
.ok()?, .ok()?,
); );
let index_worktree_cache = prevent_external_diff( let index_worktree_cache = prevent_external_diff(
@@ -194,7 +197,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
entry, entry,
status: status:
EntryStatus::Change(Change::Modification { EntryStatus::Change(Change::Modification {
content_change: Some(_), content_change: Some(()),
.. ..
}), }),
.. ..
@@ -231,7 +234,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
_ => {} _ => {}
} }
} }
}; }
diff diff
}, },
) )
@@ -382,12 +385,13 @@ impl GitDiff {
only_nonzero_diffs: bool, only_nonzero_diffs: bool,
changed: &str, changed: &str,
) -> Option<Result<&str, StringFormatterError>> { ) -> Option<Result<&str, StringFormatterError>> {
match only_nonzero_diffs { if only_nonzero_diffs {
true => match changed { match changed {
"0" => None, "0" => None,
_ => Some(Ok(changed)), _ => Some(Ok(changed)),
}, }
false => Some(Ok(changed)), } else {
Some(Ok(changed))
} }
} }
} }
+5 -14
View File
@@ -60,22 +60,12 @@ fn get_state_description<'a>(
current: None, current: None,
total: None, total: None,
}), }),
InProgress::Revert => Some(StateDescription { InProgress::Revert | InProgress::RevertSequence => Some(StateDescription {
label: config.revert, label: config.revert,
current: None, current: None,
total: None, total: None,
}), }),
InProgress::RevertSequence => Some(StateDescription { InProgress::CherryPick | InProgress::CherryPickSequence => Some(StateDescription {
label: config.revert,
current: None,
total: None,
}),
InProgress::CherryPick => Some(StateDescription {
label: config.cherry_pick,
current: None,
total: None,
}),
InProgress::CherryPickSequence => Some(StateDescription {
label: config.cherry_pick, label: config.cherry_pick,
current: None, current: None,
total: None, total: None,
@@ -95,8 +85,9 @@ fn get_state_description<'a>(
current: None, current: None,
total: None, total: None,
}), }),
InProgress::Rebase => Some(describe_rebase(repo, config.rebase)), InProgress::Rebase | InProgress::RebaseInteractive => {
InProgress::RebaseInteractive => Some(describe_rebase(repo, config.rebase)), Some(describe_rebase(repo, config.rebase))
}
} }
} }
+11 -21
View File
@@ -118,9 +118,8 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
Ok(segments) => { Ok(segments) => {
if segments.is_empty() { if segments.is_empty() {
return None; return None;
} else {
segments
} }
segments
} }
Err(error) => { Err(error) => {
log::warn!("Error in module `git_status`:\n{error}"); log::warn!("Error in module `git_status`:\n{error}");
@@ -160,27 +159,21 @@ impl<'a> GitStatusInfo<'a> {
pub fn get_repo_status(&self) -> Option<&RepoStatus> { pub fn get_repo_status(&self) -> Option<&RepoStatus> {
self.repo_status self.repo_status
.get_or_init( .get_or_init(|| {
|| match get_static_repo_status(self.context, self.repo, &self.config) { get_static_repo_status(self.context, self.repo, &self.config).or_else(|| {
Some(repo_status) => Some(repo_status),
None => {
log::debug!("get_repo_status: git status execution failed"); log::debug!("get_repo_status: git status execution failed");
None None
} })
}, })
) .as_deref()
.as_ref()
.map(|repo_status| repo_status.as_ref())
} }
pub fn get_stashed(&self) -> &Option<usize> { pub fn get_stashed(&self) -> &Option<usize> {
self.stashed_count self.stashed_count.get_or_init(|| {
.get_or_init(|| match get_stashed_count(self.repo) { get_stashed_count(self.repo).or_else(|| {
Some(stashed_count) => Some(stashed_count),
None => {
log::debug!("get_stashed_count: git stash execution failed"); log::debug!("get_stashed_count: git stash execution failed");
None None
} })
}) })
} }
@@ -380,15 +373,12 @@ fn get_repo_status(
status::Item::TreeIndex(change) => { status::Item::TreeIndex(change) => {
use gix::diff::index::Change; use gix::diff::index::Change;
match change { match change {
Change::Addition { .. } => { Change::Addition { .. } | Change::Modification { .. } => {
repo_status.staged += 1; repo_status.staged += 1;
} }
Change::Deletion { .. } => { Change::Deletion { .. } => {
repo_status.deleted += 1; repo_status.deleted += 1;
} }
Change::Modification { .. } => {
repo_status.staged += 1;
}
Change::Rewrite { .. } => { Change::Rewrite { .. } => {
repo_status.renamed += 1; repo_status.renamed += 1;
} }
@@ -550,7 +540,7 @@ impl RepoStatus {
Some('1') => self.parse_normal_status(&s[2..4]), Some('1') => self.parse_normal_status(&s[2..4]),
Some('2') => { Some('2') => {
self.renamed += 1; self.renamed += 1;
self.parse_normal_status(&s[2..4]) self.parse_normal_status(&s[2..4]);
} }
Some('u') => self.conflicted += 1, Some('u') => self.conflicted += 1,
Some('?') => self.untracked += 1, Some('?') => self.untracked += 1,
+18 -14
View File
@@ -1,3 +1,5 @@
use std::path::Path;
use crate::{ use crate::{
config::ModuleConfig, config::ModuleConfig,
configs::gradle::GradleConfig, configs::gradle::GradleConfig,
@@ -82,29 +84,31 @@ fn parse_gradle_version_from_properties(wrapper_properties: &str) -> Option<Stri
/// Tries to find the gradle-wrapper.properties file. /// Tries to find the gradle-wrapper.properties file.
fn get_wrapper_properties_file(context: &Context, recursive: bool) -> Option<String> { fn get_wrapper_properties_file(context: &Context, recursive: bool) -> Option<String> {
let mut properties = None; let read_wrapper_properties = |base_dir: &Path| {
utils::read_file(base_dir.join("gradle/wrapper/gradle-wrapper.properties")).ok()
};
// Try current directory first
if context if context
.try_begin_scan()? .try_begin_scan()?
.set_folders(&["gradle"]) .set_folders(&["gradle"])
.is_match() .is_match()
{ {
properties = utils::read_file( if let Some(properties) = read_wrapper_properties(&context.current_dir) {
context return Some(properties);
.current_dir }
.join("gradle/wrapper/gradle-wrapper.properties"), }
)
.ok(); // Try parent directories if recursive
}; if recursive {
if recursive && properties.is_none() {
for dir in context.current_dir.ancestors().skip(1) { for dir in context.current_dir.ancestors().skip(1) {
properties = if let Some(properties) = read_wrapper_properties(dir) {
utils::read_file(dir.join("gradle/wrapper/gradle-wrapper.properties")).ok(); return Some(properties);
if properties.is_some() {
break;
} }
} }
} }
properties
None
} }
#[cfg(test)] #[cfg(test)]
+1 -1
View File
@@ -15,7 +15,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
if !is_guix_shell { if !is_guix_shell {
return None; return None;
}; }
let parsed = StringFormatter::new(config.format).and_then(|formatter| { let parsed = StringFormatter::new(config.format).and_then(|formatter| {
formatter formatter
+1 -1
View File
@@ -120,7 +120,7 @@ mod tests {
assert_eq!( assert_eq!(
Some("4.3.0-rc.1+".to_string()), Some("4.3.0-rc.1+".to_string()),
parse_haxe_version(sample_haxe_output) parse_haxe_version(sample_haxe_output)
) );
} }
#[test] #[test]
+1 -1
View File
@@ -19,7 +19,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
// before it was only checking against whatever is in the config starship.toml // before it was only checking against whatever is in the config starship.toml
if config.disabled { if config.disabled {
return None; return None;
}; }
let len = if config.truncation_length <= 0 { let len = if config.truncation_length <= 0 {
log::warn!( log::warn!(
+3 -3
View File
@@ -17,7 +17,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
// before it was only checking against whatever is in the config starship.toml // before it was only checking against whatever is in the config starship.toml
if config.disabled { if config.disabled {
return None; return None;
}; }
let repo_root = context.begin_ancestor_scan().set_folders(&[".hg"]).scan()?; let repo_root = context.begin_ancestor_scan().set_folders(&[".hg"]).scan()?;
@@ -39,7 +39,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
module.set_segments(match parsed { module.set_segments(match parsed {
Ok(segments) => segments, Ok(segments) => segments,
Err(error) => { Err(error) => {
log::warn!("Error in module `hg_state`:\n{}", error); log::warn!("Error in module `hg_state`:\n{error}");
return None; return None;
} }
}); });
@@ -85,7 +85,7 @@ fn get_state_description<'a>(
label: config.merge, label: config.merge,
}) })
} else { } else {
return None; None
} }
} }
+3 -5
View File
@@ -30,12 +30,10 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
//rustc doesn't let you do an "if" and an "if let" in the same if statement //rustc doesn't let you do an "if" and an "if let" in the same if statement
// if this changes in the future this can become a lot cleaner // if this changes in the future this can become a lot cleaner
let mut host = if !config.trim_at.is_empty() { let mut host = if config.trim_at.is_empty() {
if let Some(index) = host.find(config.trim_at) {
host.split_at(index).0
} else {
host.as_ref() host.as_ref()
} } else if let Some(index) = host.find(config.trim_at) {
host.split_at(index).0
} else { } else {
host.as_ref() host.as_ref()
}; };
+9 -9
View File
@@ -46,7 +46,15 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
let default_threshold = 1; let default_threshold = 1;
let mut module_symbol = ""; let mut module_symbol = "";
let mut module_number = String::new(); let mut module_number = String::new();
if config.threshold != default_threshold { if config.threshold == default_threshold {
if num_of_jobs >= config.symbol_threshold {
module_symbol = config.symbol;
}
if num_of_jobs >= config.number_threshold {
module_number = num_of_jobs.to_string();
}
} else {
log::warn!( log::warn!(
"`threshold` in [jobs] is deprecated . Please remove it and use `symbol_threshold` and `number_threshold`." "`threshold` in [jobs] is deprecated . Please remove it and use `symbol_threshold` and `number_threshold`."
); );
@@ -61,14 +69,6 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
module_symbol = config.symbol; module_symbol = config.symbol;
module_number = num_of_jobs.to_string(); module_number = num_of_jobs.to_string();
} }
} else {
if num_of_jobs >= config.symbol_threshold {
module_symbol = config.symbol;
}
if num_of_jobs >= config.number_threshold {
module_number = num_of_jobs.to_string();
}
} }
let parsed = StringFormatter::new(config.format).and_then(|formatter| { let parsed = StringFormatter::new(config.format).and_then(|formatter| {
+6 -8
View File
@@ -82,7 +82,7 @@ fn get_aliased_name<'a>(
match replaced { match replaced {
Cow::Owned(replaced) => Some(replaced), Cow::Owned(replaced) => Some(replaced),
// It didn't match... // It didn't match...
_ => None, Cow::Borrowed(_) => None,
} }
} }
@@ -140,7 +140,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
// before it was only checking against whatever is in the config starship.toml // before it was only checking against whatever is in the config starship.toml
if config.disabled { if config.disabled {
return None; return None;
}; }
let have_env_config = !config.detect_env_vars.is_empty(); let have_env_config = !config.detect_env_vars.is_empty();
let have_env_vars = have_env_config.then(|| context.detect_env_vars(&config.detect_env_vars)); let have_env_vars = have_env_config.then(|| context.detect_env_vars(&config.detect_env_vars));
@@ -326,7 +326,7 @@ mod deprecated {
match replaced { match replaced {
// We have a match if the replaced string is different from the original // We have a match if the replaced string is different from the original
Cow::Owned(replaced) => Some(replaced), Cow::Owned(replaced) => Some(replaced),
_ => None, Cow::Borrowed(_) => None,
} }
}) })
}; };
@@ -1542,7 +1542,7 @@ users: []
} }
#[test] #[test]
fn test_json_kubeconfig_is_parsed_as_json() -> std::io::Result<()> { fn test_json_kubeconfig_is_parsed_as_json() {
let json_kubeconfig = r#"{ let json_kubeconfig = r#"{
"apiVersion": "v1", "apiVersion": "v1",
"clusters": [], "clusters": [],
@@ -1569,11 +1569,10 @@ users: []
Document::Json(..) => {} Document::Json(..) => {}
_ => panic!("Expected Document::Json, got {actual:?}"), _ => panic!("Expected Document::Json, got {actual:?}"),
} }
Ok(())
} }
#[test] #[test]
fn fallback_to_yaml_parsing() -> std::io::Result<()> { fn fallback_to_yaml_parsing() {
let json_kubeconfig = r#"{ let json_kubeconfig = r#"{
"apiVersion": v1, "apiVersion": v1,
"clusters": [], "clusters": [],
@@ -1598,9 +1597,8 @@ users: []
let actual = results.first().unwrap(); let actual = results.first().unwrap();
match actual { match actual {
Document::Yaml(..) => {} Document::Yaml(..) => {}
_ => panic!("Expected Document::Yaml, got {actual:?}"), Document::Json(_) => panic!("Expected Document::Yaml, got {actual:?}"),
} }
Ok(())
} }
#[test] #[test]
+1 -1
View File
@@ -34,7 +34,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
// before it was only checking against whatever is in the config starship.toml // before it was only checking against whatever is in the config starship.toml
if config.disabled { if config.disabled {
return None; return None;
}; }
let ssh_connection = context.get_env("SSH_CONNECTION"); let ssh_connection = context.get_env("SSH_CONNECTION");
if config.ssh_only && ssh_connection.is_none() { if config.ssh_only && ssh_connection.is_none() {
+2 -2
View File
@@ -170,7 +170,7 @@ mod test {
}) })
.collect(); .collect();
assert!(output.is_some()) assert!(output.is_some());
} }
#[test] #[test]
@@ -183,6 +183,6 @@ mod test {
}) })
.collect(); .collect();
assert!(output.is_none()) assert!(output.is_none());
} }
} }
+3 -6
View File
@@ -10,7 +10,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
if config.disabled { if config.disabled {
return None; return None;
}; }
let ctx_str = context let ctx_str = context
.exec_cmd("nats", &["context", "info", "--json"])? .exec_cmd("nats", &["context", "info", "--json"])?
@@ -53,12 +53,11 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use nu_ansi_term::Color; use nu_ansi_term::Color;
use std::io;
use crate::test::ModuleRenderer; use crate::test::ModuleRenderer;
#[test] #[test]
fn show_context() -> io::Result<()> { fn show_context() {
let actual = ModuleRenderer::new("nats") let actual = ModuleRenderer::new("nats")
.config(toml::toml! { .config(toml::toml! {
[nats] [nats]
@@ -69,11 +68,10 @@ mod tests {
.collect(); .collect();
let expected = Some(format!("{}", Color::Purple.bold().paint("localhost"))); let expected = Some(format!("{}", Color::Purple.bold().paint("localhost")));
assert_eq!(expected, actual); assert_eq!(expected, actual);
Ok(())
} }
#[test] #[test]
fn test_with_symbol() -> io::Result<()> { fn test_with_symbol() {
let actual = ModuleRenderer::new("nats") let actual = ModuleRenderer::new("nats")
.config(toml::toml! { .config(toml::toml! {
[nats] [nats]
@@ -84,6 +82,5 @@ mod tests {
.collect(); .collect();
let expected = Some(format!("{}", Color::Red.bold().paint("✉️ localhost"))); let expected = Some(format!("{}", Color::Red.bold().paint("✉️ localhost")));
assert_eq!(expected, actual); assert_eq!(expected, actual);
Ok(())
} }
} }
+1 -1
View File
@@ -95,7 +95,7 @@ mod tests {
git hash: 7e83adff84be5d0c401a213eccb61e321a3fb1ff git hash: 7e83adff84be5d0c401a213eccb61e321a3fb1ff
active boot switches: -d:release\n"; active boot switches: -d:release\n";
assert_eq!(Some("1.2.0"), parse_nim_version(sample_nimc_output)) assert_eq!(Some("1.2.0"), parse_nim_version(sample_nimc_output));
} }
#[test] #[test]
+1 -1
View File
@@ -20,7 +20,7 @@ impl NixShellType {
Some("pure") => return Some(Pure), Some("pure") => return Some(Pure),
Some("impure") => return Some(Impure), Some("impure") => return Some(Impure),
_ => {} _ => {}
}; }
if use_heuristic { if use_heuristic {
Self::in_new_nix_shell(context).map(|()| Unknown) Self::in_new_nix_shell(context).map(|()| Unknown)
+3 -3
View File
@@ -101,10 +101,10 @@ fn parse_opam_switch(opam_switch: &str) -> Option<OpamSwitch> {
} }
let path = Path::new(opam_switch); let path = Path::new(opam_switch);
if !path.has_root() { if path.has_root() {
Some((SwitchType::Global, opam_switch.to_string()))
} else {
Some((SwitchType::Local, path.file_name()?.to_str()?.to_string())) Some((SwitchType::Local, path.file_name()?.to_str()?.to_string()))
} else {
Some((SwitchType::Global, opam_switch.to_string()))
} }
} }
+2 -2
View File
@@ -62,10 +62,10 @@ fn get_opa_version(context: &Context) -> Option<String> {
let version_output: String = context let version_output: String = context
.exec_cmd("opa", &["version"]) .exec_cmd("opa", &["version"])
.map(get_command_string_output)?; .map(get_command_string_output)?;
parse_opa_version(version_output) parse_opa_version(&version_output)
} }
fn parse_opa_version(version_output: String) -> Option<String> { fn parse_opa_version(version_output: &str) -> Option<String> {
Some(version_output.split_whitespace().nth(1)?.to_string()) Some(version_output.split_whitespace().nth(1)?.to_string())
} }
+7 -8
View File
@@ -21,7 +21,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
let parsed = StringFormatter::new(config.format).and_then(|formatter| { let parsed = StringFormatter::new(config.format).and_then(|formatter| {
formatter formatter
.map_meta(|variable, _| match variable { .map_meta(|variable, _| match variable {
"symbol" => get_symbol(&config, &os.os_type()), "symbol" => get_symbol(&config, os.os_type()),
_ => None, _ => None,
}) })
.map_style(|variable| match variable { .map_style(|variable| match variable {
@@ -51,7 +51,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
// Get the operating system symbol from user config, or else default config // Get the operating system symbol from user config, or else default config
// when user has not defined a symbol for the operating system. // 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> { fn get_symbol<'a>(config: &'a OSConfig, os_type: os_info::Type) -> Option<&'a str> {
config config
.get_symbol(os_type) .get_symbol(os_type)
.or_else(|| OSConfig::default().get_symbol(os_type)) .or_else(|| OSConfig::default().get_symbol(os_type))
@@ -171,7 +171,7 @@ mod tests {
]; ];
for (t, e) in type_expected_pairs { for (t, e) in type_expected_pairs {
assert_eq!(get_symbol(&config, &t), e); assert_eq!(get_symbol(&config, t), e);
} }
} }
@@ -261,7 +261,7 @@ mod tests {
]; ];
for (t, e) in type_expected_pairs { for (t, e) in type_expected_pairs {
assert_eq!(get_symbol(&config, &t), e); assert_eq!(get_symbol(&config, t), e);
} }
} }
@@ -316,7 +316,7 @@ mod tests {
]; ];
for (t, e) in type_expected_pairs { for (t, e) in type_expected_pairs {
assert_eq!(get_symbol(&config, &t), e); assert_eq!(get_symbol(&config, t), e);
} }
} }
@@ -344,11 +344,12 @@ mod tests {
Type::Arch | Type::Artix | Type::CachyOS => "🎗️ ", Type::Arch | Type::Artix | Type::CachyOS => "🎗️ ",
Type::Bluefin => "🐟 ", Type::Bluefin => "🐟 ",
Type::CentOS | Type::AlmaLinux | Type::RockyLinux => "💠 ", Type::CentOS | Type::AlmaLinux | Type::RockyLinux => "💠 ",
Type::Cygwin => "",
Type::Debian => "🌀 ", Type::Debian => "🌀 ",
Type::DragonFly => "🐉 ", Type::DragonFly => "🐉 ",
Type::Emscripten => "🔗 ", Type::Emscripten => "🔗 ",
Type::EndeavourOS => "🚀 ", Type::EndeavourOS => "🚀 ",
Type::Fedora | Type::Nobara => "🎩 ", Type::Fedora | Type::Nobara | Type::Redhat | Type::RedHatEnterprise => "🎩 ",
Type::FreeBSD => "😈 ", Type::FreeBSD => "😈 ",
Type::Garuda => "🦅 ", Type::Garuda => "🦅 ",
Type::Gentoo => "🗜️ ", Type::Gentoo => "🗜️ ",
@@ -371,8 +372,6 @@ mod tests {
Type::OracleLinux => "🦴 ", Type::OracleLinux => "🦴 ",
Type::Pop => "🍭 ", Type::Pop => "🍭 ",
Type::Raspbian => "🍓 ", Type::Raspbian => "🍓 ",
Type::Redhat => "🎩 ",
Type::RedHatEnterprise => "🎩 ",
Type::Redox => "🧪 ", Type::Redox => "🧪 ",
Type::Solus => "", Type::Solus => "",
Type::SUSE => "🦎 ", Type::SUSE => "🦎 ",
+5 -4
View File
@@ -3,6 +3,7 @@ use crate::configs::package::PackageConfig;
use crate::formatter::{StringFormatter, VersionFormatter}; use crate::formatter::{StringFormatter, VersionFormatter};
use ini::Ini; use ini::Ini;
use jsonc_parser::ParseOptions;
use quick_xml::Reader as QXReader; use quick_xml::Reader as QXReader;
use quick_xml::events::Event as QXEvent; use quick_xml::events::Event as QXEvent;
use regex::Regex; use regex::Regex;
@@ -57,13 +58,13 @@ fn get_node_package_version(context: &Context, config: &PackageConfig) -> Option
let raw_version = package_json.get("version")?.as_str()?; let raw_version = package_json.get("version")?.as_str()?;
if raw_version == "null" { if raw_version == "null" {
return None; return None;
}; }
let formatted_version = format_version(raw_version, config.version_format)?; let formatted_version = format_version(raw_version, config.version_format)?;
if formatted_version == "v0.0.0-development" || formatted_version.starts_with("v0.0.0-semantic") if formatted_version == "v0.0.0-development" || formatted_version.starts_with("v0.0.0-semantic")
{ {
return Some("semantic".to_string()); return Some("semantic".to_string());
}; }
Some(formatted_version) Some(formatted_version)
} }
@@ -78,7 +79,7 @@ fn get_jsr_package_version(context: &Context, config: &PackageConfig) -> Option<
})?; })?;
let json_content: json::Value = if filename.ends_with(".jsonc") { let json_content: json::Value = if filename.ends_with(".jsonc") {
jsonc_parser::parse_to_serde_value(&contents, &Default::default()).ok()?? jsonc_parser::parse_to_serde_value(&contents, &ParseOptions::default()).ok()??
} else { } else {
json::from_str(&contents).ok()? json::from_str(&contents).ok()?
}; };
@@ -298,7 +299,7 @@ fn get_nimble_version(context: &Context, config: &PackageConfig) -> Option<Strin
.is_match() .is_match()
{ {
return None; return None;
}; }
let cmd_output = context.exec_cmd("nimble", &["dump", "--json"])?; let cmd_output = context.exec_cmd("nimble", &["dump", "--json"])?;
let nimble_json: json::Value = json::from_str(&cmd_output.stdout).ok()?; let nimble_json: json::Value = json::from_str(&cmd_output.stdout).ok()?;
+1 -1
View File
@@ -23,7 +23,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
// We default to disabled=true, so we have to check after loading our config module. // We default to disabled=true, so we have to check after loading our config module.
if config.disabled { if config.disabled {
return None; return None;
}; }
let channel_name = get_pijul_current_channel(context)?; let channel_name = get_pijul_current_channel(context)?;
+1 -1
View File
@@ -77,7 +77,7 @@ fn get_pixi_version(context: &Context, config: &PixiConfig) -> Option<String> {
.find_map(|binary| context.exec_cmd(binary, &["--version"])) .find_map(|binary| context.exec_cmd(binary, &["--version"]))
.map(get_command_string_output)?; .map(get_command_string_output)?;
Some(version.split_once(" ")?.1.trim().to_string()) Some(version.split_once(' ')?.1.trim().to_string())
} }
#[cfg(test)] #[cfg(test)]
+7 -8
View File
@@ -96,9 +96,8 @@ fn parse_version(version: &str) -> &str {
if *c == b'.' { if *c == b'.' {
if periods == 2 { if periods == 2 {
return &sanitized_version[0..i]; return &sanitized_version[0..i];
} else {
periods += 1;
} }
periods += 1;
} }
} }
// We didn't hit 3 periods, so we just return the whole string. // We didn't hit 3 periods, so we just return the whole string.
@@ -210,7 +209,7 @@ mod tests {
use std::io; use std::io;
use super::*; use super::*;
use crate::context::Target; use crate::context::{Properties, Target};
use crate::test::ModuleRenderer; use crate::test::ModuleRenderer;
use nu_ansi_term::Color; use nu_ansi_term::Color;
@@ -267,19 +266,19 @@ mod tests {
#[test] #[test]
fn get_home_dir() { fn get_home_dir() {
let mut context = Context::new(Default::default(), Target::Main); let mut context = Context::new(Properties::default(), Target::Main);
context.env.insert("HOME", "/home/sweet/home".to_string()); context.env.insert("HOME", "/home/sweet/home".to_string());
assert_eq!( assert_eq!(
pulumi_home_dir(&context), pulumi_home_dir(&context),
Some(PathBuf::from("/home/sweet/home/.pulumi")) Some(PathBuf::from("/home/sweet/home/.pulumi"))
); );
context.env.insert("PULUMI_HOME", "/a/dir".to_string()); context.env.insert("PULUMI_HOME", "/a/dir".to_string());
assert_eq!(pulumi_home_dir(&context), Some(PathBuf::from("/a/dir"))) assert_eq!(pulumi_home_dir(&context), Some(PathBuf::from("/a/dir")));
} }
#[test] #[test]
fn test_get_pulumi_workspace() { fn test_get_pulumi_workspace() {
let mut context = Context::new(Default::default(), Target::Main); let mut context = Context::new(Properties::default(), Target::Main);
context.env.insert("HOME", "/home/sweet/home".to_string()); context.env.insert("HOME", "/home/sweet/home".to_string());
let name = "foobar"; let name = "foobar";
let project_file = PathBuf::from("/hello/Pulumi.yaml"); let project_file = PathBuf::from("/hello/Pulumi.yaml");
@@ -362,7 +361,7 @@ mod tests {
credential.sync_all()?; credential.sync_all()?;
let rendered = module_renderer let rendered = module_renderer
.path(root.clone()) .path(root.clone())
.logical_path(root.clone()) .logical_path(root)
.config(toml::toml! { .config(toml::toml! {
[pulumi] [pulumi]
format = "via [$symbol($username@)$stack]($style) " format = "via [$symbol($username@)$stack]($style) "
@@ -422,7 +421,7 @@ mod tests {
credential.sync_all()?; credential.sync_all()?;
let rendered = module_renderer let rendered = module_renderer
.path(root.clone()) .path(root.clone())
.logical_path(root.clone()) .logical_path(root)
.config(toml::toml! { .config(toml::toml! {
[pulumi] [pulumi]
format = "via [$symbol($username@)$stack]($style) " format = "via [$symbol($username@)$stack]($style) "
+2 -2
View File
@@ -24,7 +24,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
if !is_py_project && !has_env_vars { if !is_py_project && !has_env_vars {
return None; return None;
}; }
let pyenv_prefix = if config.pyenv_version_name { let pyenv_prefix = if config.pyenv_version_name {
config.pyenv_prefix config.pyenv_prefix
@@ -86,7 +86,7 @@ fn get_pyenv_version(context: &Context) -> Option<String> {
.stdout .stdout
.trim() .trim()
.to_string(), .to_string(),
) );
} }
version_name version_name
+19 -19
View File
@@ -466,9 +466,9 @@ impl RustupSettings {
fn from_toml_str(toml_str: &str) -> Option<Self> { fn from_toml_str(toml_str: &str) -> Option<Self> {
let settings = toml::from_str::<Self>(toml_str).ok()?; let settings = toml::from_str::<Self>(toml_str).ok()?;
match settings.version.as_deref() { if settings.version.as_deref() == Some("12") {
Some("12") => Some(settings), Some(settings)
_ => { } else {
log::warn!( log::warn!(
r#"Rustup settings version is {:?}, expected "12""#, r#"Rustup settings version is {:?}, expected "12""#,
settings.version settings.version
@@ -476,7 +476,6 @@ impl RustupSettings {
None None
} }
} }
}
fn default_host_triple(&self) -> Option<&str> { fn default_host_triple(&self) -> Option<&str> {
self.default_host_triple.as_deref() self.default_host_triple.as_deref()
@@ -499,7 +498,8 @@ impl RustupSettings {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::context::{Shell, Target}; use crate::context::{Properties, Shell, Target};
use crate::context_env::Env;
use std::io; use std::io;
use std::process::{ExitStatus, Output}; use std::process::{ExitStatus, Output};
use std::sync::LazyLock; use std::sync::LazyLock;
@@ -735,7 +735,7 @@ version = "12"
Target::Main, Target::Main,
dir.path().into(), dir.path().into(),
dir.path().into(), dir.path().into(),
Default::default(), Env::default(),
); );
assert_eq!( assert_eq!(
@@ -752,12 +752,12 @@ version = "12"
)?; )?;
let context = Context::new_with_shell_and_path( let context = Context::new_with_shell_and_path(
Default::default(), Properties::default(),
Shell::Unknown, Shell::Unknown,
Target::Main, Target::Main,
dir.path().into(), dir.path().into(),
dir.path().into(), dir.path().into(),
Default::default(), Env::default(),
); );
assert_eq!( assert_eq!(
@@ -779,7 +779,7 @@ version = "12"
Target::Main, Target::Main,
dir.path().into(), dir.path().into(),
dir.path().into(), dir.path().into(),
Default::default(), Env::default(),
); );
assert_eq!( assert_eq!(
@@ -798,12 +798,12 @@ version = "12"
)?; )?;
let context = Context::new_with_shell_and_path( let context = Context::new_with_shell_and_path(
Default::default(), Properties::default(),
Shell::Unknown, Shell::Unknown,
Target::Main, Target::Main,
child_dir_path.clone(), child_dir_path.clone(),
child_dir_path, child_dir_path,
Default::default(), Env::default(),
); );
assert_eq!( assert_eq!(
@@ -819,12 +819,12 @@ version = "12"
fs::write(dir.path().join("rust-toolchain.toml"), "1.34.0")?; fs::write(dir.path().join("rust-toolchain.toml"), "1.34.0")?;
let context = Context::new_with_shell_and_path( let context = Context::new_with_shell_and_path(
Default::default(), Properties::default(),
Shell::Unknown, Shell::Unknown,
Target::Main, Target::Main,
dir.path().into(), dir.path().into(),
dir.path().into(), dir.path().into(),
Default::default(), Env::default(),
); );
assert_eq!(find_rust_toolchain_file(&context), None); assert_eq!(find_rust_toolchain_file(&context), None);
@@ -838,12 +838,12 @@ version = "12"
)?; )?;
let context = Context::new_with_shell_and_path( let context = Context::new_with_shell_and_path(
Default::default(), Properties::default(),
Shell::Unknown, Shell::Unknown,
Target::Main, Target::Main,
dir.path().into(), dir.path().into(),
dir.path().into(), dir.path().into(),
Default::default(), Env::default(),
); );
assert_eq!( assert_eq!(
@@ -860,12 +860,12 @@ version = "12"
)?; )?;
let context = Context::new_with_shell_and_path( let context = Context::new_with_shell_and_path(
Default::default(), Properties::default(),
Shell::Unknown, Shell::Unknown,
Target::Main, Target::Main,
dir.path().into(), dir.path().into(),
dir.path().into(), dir.path().into(),
Default::default(), Env::default(),
); );
assert_eq!( assert_eq!(
@@ -884,12 +884,12 @@ version = "12"
)?; )?;
let context = Context::new_with_shell_and_path( let context = Context::new_with_shell_and_path(
Default::default(), Properties::default(),
Shell::Unknown, Shell::Unknown,
Target::Main, Target::Main,
child_dir_path.clone(), child_dir_path.clone(),
child_dir_path, child_dir_path,
Default::default(), Env::default(),
); );
assert_eq!( assert_eq!(
+3 -3
View File
@@ -39,10 +39,10 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
} }
} }
let symbol = if repeat_count != 1 { let symbol = if repeat_count == 1 {
Cow::Owned(config.symbol.repeat(repeat_count))
} else {
Cow::Borrowed(config.symbol) Cow::Borrowed(config.symbol)
} else {
Cow::Owned(config.symbol.repeat(repeat_count))
}; };
let parsed = StringFormatter::new(config.format).and_then(|formatter| { let parsed = StringFormatter::new(config.format).and_then(|formatter| {
+27 -22
View File
@@ -26,21 +26,25 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
// before it was only checking against whatever is in the config starship.toml // before it was only checking against whatever is in the config starship.toml
if config.disabled { if config.disabled {
return None; return None;
}; }
let exit_code = context.properties.status_code.as_deref().unwrap_or("0"); let exit_code = context.properties.status_code.as_deref().unwrap_or("0");
let pipestatus_status = match &context.properties.pipestatus { let pipestatus_status = match &context.properties.pipestatus {
None => PipeStatusStatus::Disabled, None => PipeStatusStatus::Disabled,
Some(ps) => match ps.len() > 1 { Some(ps) => {
true => PipeStatusStatus::Pipe(ps), if ps.len() > 1 {
false => PipeStatusStatus::NoPipe, PipeStatusStatus::Pipe(ps)
}, } else {
PipeStatusStatus::NoPipe
}
}
}; };
let pipestatus_status = match config.pipestatus { let pipestatus_status = if config.pipestatus {
true => pipestatus_status, pipestatus_status
false => PipeStatusStatus::Disabled, } else {
PipeStatusStatus::Disabled
}; };
// Exit code is zero while success_symbol and pipestatus are all zero or disabled/missing // Exit code is zero while success_symbol and pipestatus are all zero or disabled/missing
@@ -91,7 +95,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
PipeStatusStatus::Pipe(_) => config.pipestatus_format, PipeStatusStatus::Pipe(_) => config.pipestatus_format,
_ => config.format, _ => config.format,
}; };
let parsed = format_exit_code(exit_code, main_format, Some(pipestatus), &config, context); let parsed = format_exit_code(exit_code, main_format, Some(&pipestatus), &config, context);
module.set_segments(match parsed { module.set_segments(match parsed {
Ok(segments) => segments, Ok(segments) => segments,
@@ -106,35 +110,36 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
fn format_exit_code<'a>( fn format_exit_code<'a>(
exit_code: &'a str, exit_code: &'a str,
format: &'a str, format: &'a str,
pipestatus: Option<Vec<Segment>>, pipestatus: Option<&Vec<Segment>>,
config: &'a StatusConfig, config: &'a StatusConfig,
context: &'a Context, context: &'a Context,
) -> Result<Vec<Segment>, StringFormatterError> { ) -> Result<Vec<Segment>, StringFormatterError> {
// First, parse as i64 to accept both i32 or u32, then normalize to i32. // First, parse as i64 to accept both i32 or u32, then normalize to i32.
let exit_code_int: ExitCode = match exit_code.parse::<i64>() { let exit_code_int = if let Ok(i) = exit_code.parse::<i64>() {
Ok(i) => i as ExitCode, i as ExitCode
Err(_) => { } else {
log::warn!("Error parsing exit_code string to int"); log::warn!("Error parsing exit_code string to int");
return Ok(Vec::new()); return Ok(Vec::new());
}
}; };
let hex_status = format!("0x{exit_code_int:X}"); let hex_status = format!("0x{exit_code_int:X}");
let common_meaning = status_common_meaning(exit_code_int); let common_meaning = status_common_meaning(exit_code_int);
let raw_signal_number = match config.recognize_signal_code { let raw_signal_number = if config.recognize_signal_code {
true => status_to_signal(exit_code_int), status_to_signal(exit_code_int)
false => None, } else {
None
}; };
let signal_number = raw_signal_number.map(|sn| sn.to_string()); let signal_number = raw_signal_number.map(|sn| sn.to_string());
let signal_name = let signal_name =
raw_signal_number.and_then(|sn| status_signal_name(sn).or(signal_number.as_deref())); raw_signal_number.and_then(|sn| status_signal_name(sn).or(signal_number.as_deref()));
// If not a signal and not a common meaning, it should at least print the raw exit code number // If not a signal and not a common meaning, it should at least print the raw exit code number
let maybe_exit_code_number = match common_meaning.is_none() && signal_name.is_none() { let maybe_exit_code_number = if common_meaning.is_none() && signal_name.is_none() {
true => Some(exit_code), Some(exit_code)
false => None, } else {
None
}; };
StringFormatter::new(format).and_then(|formatter| { StringFormatter::new(format).and_then(|formatter| {
@@ -184,7 +189,7 @@ fn format_exit_code<'a>(
log::warn!("pipestatus variable is only available in pipestatus_format"); log::warn!("pipestatus variable is only available in pipestatus_format");
None None
} }
"pipestatus" => pipestatus.clone().map(Ok), "pipestatus" => pipestatus.cloned().map(Ok),
_ => None, _ => None,
}) })
.parse(None, Some(context)) .parse(None, Some(context))
@@ -835,7 +840,7 @@ mod tests {
.pipestatus(pipe_exit_code) .pipestatus(pipe_exit_code)
.width(100); .width(100);
let context = crate::modules::Context::from(renderer); let context = crate::modules::Context::from(renderer);
let actual = crate::print::get_prompt(context); let actual = crate::print::get_prompt(&context);
let mut escaping = false; let mut escaping = false;
let mut width = 0; let mut width = 0;
+9 -13
View File
@@ -13,7 +13,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
// before it was only checking against whatever is in the config starship.toml // before it was only checking against whatever is in the config starship.toml
if config.disabled { if config.disabled {
return None; return None;
}; }
// Hide prompt if current time is not inside time_range // Hide prompt if current time is not inside time_range
let (display_start, display_end) = parse_time_range(config.time_range); let (display_start, display_end) = parse_time_range(config.time_range);
@@ -27,19 +27,15 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
log::trace!("Timer module is enabled with format string: {time_format}"); log::trace!("Timer module is enabled with format string: {time_format}");
let formatted_time_string = if config.utc_time_offset != "local" { let formatted_time_string = create_offset_time_string(
match create_offset_time_string(Utc::now(), config.utc_time_offset, time_format) { Utc::now(),
Ok(formatted_string) => formatted_string, config.utc_time_offset,
Err(_) => { time_format,
log::warn!( )
"Invalid utc_time_offset configuration provided! Falling back to \"local\"." .unwrap_or_else(|_| {
); log::warn!("Invalid utc_time_offset configuration provided! Falling back to \"local\".");
format_time(time_format, Local::now()) format_time(time_format, Local::now())
} });
}
} else {
format_time(time_format, Local::now())
};
let parsed = StringFormatter::new(config.format).and_then(|formatter| { let parsed = StringFormatter::new(config.format).and_then(|formatter| {
formatter formatter
+3 -3
View File
@@ -31,21 +31,21 @@ mod tests {
fn truncate_smaller_path_than_provided_length() { fn truncate_smaller_path_than_provided_length() {
let path = "~/starship"; let path = "~/starship";
let output = truncate(path, 3); let output = truncate(path, 3);
assert_eq!(output, None) assert_eq!(output, None);
} }
#[test] #[test]
fn truncate_same_path_as_provided_length() { fn truncate_same_path_as_provided_length() {
let path = "~/starship/engines"; let path = "~/starship/engines";
let output = truncate(path, 3); let output = truncate(path, 3);
assert_eq!(output, None) assert_eq!(output, None);
} }
#[test] #[test]
fn truncate_slightly_larger_path_than_provided_length() { fn truncate_slightly_larger_path_than_provided_length() {
let path = "~/starship/engines/booster"; let path = "~/starship/engines/booster";
let output = truncate(path, 3); let output = truncate(path, 3);
assert_eq!(output.as_deref(), Some("starship/engines/booster")) assert_eq!(output.as_deref(), Some("starship/engines/booster"));
} }
#[test] #[test]
+5 -4
View File
@@ -38,10 +38,11 @@ pub fn is_write_allowed(folder_path: &Path) -> Result<bool, String> {
#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios"))))] #[cfg(all(unix, not(any(target_os = "macos", target_os = "ios"))))]
fn get_supplementary_groups() -> Vec<u32> { fn get_supplementary_groups() -> Vec<u32> {
match nix::unistd::getgroups() { nix::unistd::getgroups()
Err(_) => Vec::new(), .unwrap_or_default()
Ok(v) => v.into_iter().map(nix::unistd::Gid::as_raw).collect(), .into_iter()
} .map(nix::unistd::Gid::as_raw)
.collect()
} }
#[cfg(all(unix, any(target_os = "macos", target_os = "ios")))] #[cfg(all(unix, any(target_os = "macos", target_os = "ios")))]
+10 -11
View File
@@ -12,7 +12,6 @@ pub fn truncate_text(text: &str, length: usize, truncation_symbol: &str) -> Stri
let truncated_graphemes = get_graphemes(text, length); let truncated_graphemes = get_graphemes(text, length);
// The truncation symbol should only be added if we truncated // The truncation symbol should only be added if we truncated
if length < graphemes_len(text) { if length < graphemes_len(text) {
let truncation_symbol = get_graphemes(truncation_symbol, 1); let truncation_symbol = get_graphemes(truncation_symbol, 1);
truncated_graphemes + truncation_symbol.as_str() truncated_graphemes + truncation_symbol.as_str()
@@ -45,52 +44,52 @@ mod tests {
#[test] #[test]
fn test_changed_truncation_symbol() { fn test_changed_truncation_symbol() {
test_truncate_length("1337_hello_world", 15, "1337_hello_worl", "%") test_truncate_length("1337_hello_world", 15, "1337_hello_worl", "%");
} }
#[test] #[test]
fn test_no_truncation_symbol() { fn test_no_truncation_symbol() {
test_truncate_length("1337_hello_world", 15, "1337_hello_worl", "") test_truncate_length("1337_hello_world", 15, "1337_hello_worl", "");
} }
#[test] #[test]
fn test_ascii_boundary_below() { fn test_ascii_boundary_below() {
test_truncate_length("1337_hello_world", 15, "1337_hello_worl", "") test_truncate_length("1337_hello_world", 15, "1337_hello_worl", "");
} }
#[test] #[test]
fn test_ascii_boundary_on() { fn test_ascii_boundary_on() {
test_truncate_length("1337_hello_world", 16, "1337_hello_world", "") test_truncate_length("1337_hello_world", 16, "1337_hello_world", "");
} }
#[test] #[test]
fn test_ascii_boundary_above() { fn test_ascii_boundary_above() {
test_truncate_length("1337_hello_world", 17, "1337_hello_world", "") test_truncate_length("1337_hello_world", 17, "1337_hello_world", "");
} }
#[test] #[test]
fn test_one() { fn test_one() {
test_truncate_length("1337_hello_world", 1, "1", "") test_truncate_length("1337_hello_world", 1, "1", "");
} }
#[test] #[test]
fn test_negative() { fn test_negative() {
test_truncate_length("1337_hello_world", -1, "1337_hello_world", "") test_truncate_length("1337_hello_world", -1, "1337_hello_world", "");
} }
#[test] #[test]
fn test_hindi_truncation() { fn test_hindi_truncation() {
test_truncate_length("नमस्ते", 2, "नम", "") test_truncate_length("नमस्ते", 2, "नम", "");
} }
#[test] #[test]
fn test_hindi_truncation2() { fn test_hindi_truncation2() {
test_truncate_length("नमस्त", 2, "नम", "") test_truncate_length("नमस्त", 2, "नम", "");
} }
#[test] #[test]
fn test_japanese_truncation() { fn test_japanese_truncation() {
test_truncate_length("がんばってね", 4, "がんばっ", "") test_truncate_length("がんばってね", 4, "がんばっ", "");
} }
fn test_truncate_length( fn test_truncate_length(
+1 -1
View File
@@ -77,7 +77,7 @@ mod tests {
#[test] #[test]
fn test_parse_v_version() { fn test_parse_v_version() {
const OUTPUT: &str = "V 0.2 30c0659\n"; const OUTPUT: &str = "V 0.2 30c0659\n";
assert_eq!(parse_v_version(OUTPUT), Some("0.2".to_string())) assert_eq!(parse_v_version(OUTPUT), Some("0.2".to_string()));
} }
#[test] #[test]
+29 -29
View File
@@ -61,10 +61,10 @@ pub fn prompt(args: Properties, target: Target) {
let context = Context::new(args, target); let context = Context::new(args, target);
let stdout = io::stdout(); let stdout = io::stdout();
let mut handle = stdout.lock(); let mut handle = stdout.lock();
write!(handle, "{}", get_prompt(context)).unwrap(); write!(handle, "{}", get_prompt(&context)).unwrap();
} }
pub fn get_prompt(context: Context) -> String { pub fn get_prompt(context: &Context) -> String {
let config = &context.root_config; let config = &context.root_config;
let mut buf = String::new(); let mut buf = String::new();
@@ -83,7 +83,7 @@ pub fn get_prompt(context: Context) -> String {
buf.push_str("\x1b[J"); // An ASCII control code to clear screen buf.push_str("\x1b[J"); // An ASCII control code to clear screen
} }
let (formatter, modules) = load_formatter_and_modules(&context); let (formatter, modules) = load_formatter_and_modules(context);
let formatter = formatter.map_variables_to_segments(|module| { let formatter = formatter.map_variables_to_segments(|module| {
// Make $all display all modules not explicitly referenced // Make $all display all modules not explicitly referenced
@@ -91,7 +91,7 @@ pub fn get_prompt(context: Context) -> String {
Some(Ok(all_modules_uniq(&modules) Some(Ok(all_modules_uniq(&modules)
.par_iter() .par_iter()
.flat_map(|module| { .flat_map(|module| {
handle_module(module, &context, &modules) handle_module(module, context, &modules)
.into_iter() .into_iter()
.flat_map(|module| module.segments) .flat_map(|module| module.segments)
.collect::<Vec<Segment>>() .collect::<Vec<Segment>>()
@@ -101,7 +101,7 @@ pub fn get_prompt(context: Context) -> String {
None None
} else { } else {
// Get segments from module // Get segments from module
Some(Ok(handle_module(module, &context, &modules) Some(Ok(handle_module(module, context, &modules)
.into_iter() .into_iter()
.flat_map(|module| module.segments) .flat_map(|module| module.segments)
.collect::<Vec<Segment>>())) .collect::<Vec<Segment>>()))
@@ -112,7 +112,7 @@ pub fn get_prompt(context: Context) -> String {
let mut root_module = Module::new("Starship Root", "The root module", None); let mut root_module = Module::new("Starship Root", "The root module", None);
root_module.set_segments( root_module.set_segments(
formatter formatter
.parse(None, Some(&context)) .parse(None, Some(context))
.expect("Unexpected error returned in root format variables"), .expect("Unexpected error returned in root format variables"),
); );
@@ -144,12 +144,12 @@ pub fn get_prompt(context: Context) -> String {
pub fn module(module_name: &str, args: Properties) { pub fn module(module_name: &str, args: Properties) {
let context = Context::new(args, Target::Main); let context = Context::new(args, Target::Main);
let module = get_module(module_name, context).unwrap_or_default(); let module = get_module(module_name, &context).unwrap_or_default();
print!("{module}"); print!("{module}");
} }
pub fn get_module(module_name: &str, context: Context) -> Option<String> { pub fn get_module(module_name: &str, context: &Context) -> Option<String> {
modules::handle(module_name, &context).map(|m| m.to_string()) modules::handle(module_name, context).map(|m| m.to_string())
} }
pub fn timings(args: Properties) { pub fn timings(args: Properties) {
@@ -289,7 +289,7 @@ pub fn explain(args: Properties) {
" ".repeat(max_module_width - info.value_len), " ".repeat(max_module_width - info.value_len),
info.desc, info.desc,
); );
}; }
} }
} }
@@ -404,7 +404,7 @@ fn all_modules_uniq(module_list: &BTreeSet<String>) -> Vec<String> {
let mut prompt_order: Vec<String> = Vec::new(); let mut prompt_order: Vec<String> = Vec::new();
for module in PROMPT_ORDER { for module in PROMPT_ORDER {
if !module_list.contains(*module) { if !module_list.contains(*module) {
prompt_order.push(String::from(*module)) prompt_order.push(String::from(*module));
} }
} }
@@ -454,7 +454,7 @@ fn load_formatter_and_modules<'a>(context: &'a Context) -> (StringFormatter<'a>,
"format".to_string() "format".to_string()
}; };
log::error!("Error parsing {name:?}: {e}"); log::error!("Error parsing {name:?}: {e}");
}; }
if let Err(ref e) = rf { if let Err(ref e) = rf {
log::error!("Error parsing right_format: {e}"); log::error!("Error parsing right_format: {e}");
@@ -541,7 +541,7 @@ mod test {
context.target = Target::Main; context.target = Target::Main;
let expected = String::from(">\n>"); let expected = String::from(">\n>");
let actual = get_prompt(context); let actual = get_prompt(&context);
assert_eq!(expected, actual); assert_eq!(expected, actual);
} }
@@ -555,7 +555,7 @@ mod test {
context.target = Target::Right; context.target = Target::Right;
let expected = String::from(">>"); // should strip new lines let expected = String::from(">>"); // should strip new lines
let actual = get_prompt(context); let actual = get_prompt(&context);
assert_eq!(expected, actual); assert_eq!(expected, actual);
} }
@@ -572,7 +572,7 @@ mod test {
context.current_dir = dir.path().to_path_buf(); context.current_dir = dir.path().to_path_buf();
let expected = String::from(">"); let expected = String::from(">");
let actual = get_prompt(context); let actual = get_prompt(&context);
assert_eq!(expected, actual); assert_eq!(expected, actual);
dir.close() dir.close()
} }
@@ -591,7 +591,7 @@ mod test {
context.target = Target::Right; context.target = Target::Right;
let expected = String::from(">"); let expected = String::from(">");
let actual = get_prompt(context); let actual = get_prompt(&context);
assert_eq!(expected, actual); assert_eq!(expected, actual);
dir.close() dir.close()
} }
@@ -608,7 +608,7 @@ mod test {
context.target = Target::Profile("test".to_string()); context.target = Target::Profile("test".to_string());
let expected = String::from("0_0>>"); let expected = String::from("0_0>>");
let actual = get_prompt(context); let actual = get_prompt(&context);
assert_eq!(expected, actual); assert_eq!(expected, actual);
} }
@@ -624,7 +624,7 @@ mod test {
context.target = Target::Profile("wrong_prompt".to_string()); context.target = Target::Profile("wrong_prompt".to_string());
let expected = String::from(">"); let expected = String::from(">");
let actual = get_prompt(context); let actual = get_prompt(&context);
assert_eq!(expected, actual); assert_eq!(expected, actual);
} }
@@ -636,21 +636,21 @@ mod test {
context.target = Target::Continuation; context.target = Target::Continuation;
let expected = String::from("><>"); let expected = String::from("><>");
let actual = get_prompt(context); let actual = get_prompt(&context);
assert_eq!(expected, actual); assert_eq!(expected, actual);
} }
#[test] #[test]
fn preset_list_returns_one_or_more_items() { fn preset_list_returns_one_or_more_items() {
assert!(preset_list().trim().split('\n').count() > 0); assert!(preset_list().lines().count() > 0);
} }
#[test] #[test]
fn preset_command_does_not_panic_on_correct_inputs() { fn preset_command_does_not_panic_on_correct_inputs() {
preset_command(None, None, true); preset_command(None, None, true);
Preset::value_variants() for v in Preset::value_variants() {
.iter() preset_command(Some(v.clone()), None, false);
.for_each(|v| preset_command(Some(v.clone()), None, false)); }
} }
#[test] #[test]
@@ -687,7 +687,7 @@ mod test {
context.current_dir = dir.path().to_path_buf(); context.current_dir = dir.path().to_path_buf();
let expected = String::from("\nab"); let expected = String::from("\nab");
let actual = get_prompt(context); let actual = get_prompt(&context);
assert_eq!(expected, actual); assert_eq!(expected, actual);
dir.close() dir.close()
} }
@@ -709,7 +709,7 @@ mod test {
context.env.insert("c", "c".to_string()); context.env.insert("c", "c".to_string());
let expected = String::from("\nabc"); let expected = String::from("\nabc");
let actual = get_prompt(context); let actual = get_prompt(&context);
assert_eq!(expected, actual); assert_eq!(expected, actual);
} }
@@ -731,7 +731,7 @@ mod test {
context.current_dir = dir.path().to_path_buf(); context.current_dir = dir.path().to_path_buf();
let expected = String::from("\ncab"); let expected = String::from("\ncab");
let actual = get_prompt(context); let actual = get_prompt(&context);
assert_eq!(expected, actual); assert_eq!(expected, actual);
dir.close() dir.close()
} }
@@ -756,7 +756,7 @@ mod test {
context.env.insert("d", "d".to_string()); context.env.insert("d", "d".to_string());
let expected = String::from("\ncdab"); let expected = String::from("\ncdab");
let actual = get_prompt(context); let actual = get_prompt(&context);
assert_eq!(expected, actual); assert_eq!(expected, actual);
} }
@@ -775,7 +775,7 @@ mod test {
context.current_dir = dir.path().to_path_buf(); context.current_dir = dir.path().to_path_buf();
let expected = String::from("\nb"); let expected = String::from("\nb");
let actual = get_prompt(context); let actual = get_prompt(&context);
assert_eq!(expected, actual); assert_eq!(expected, actual);
dir.close() dir.close()
} }
@@ -792,7 +792,7 @@ mod test {
context.current_dir = dir.path().to_path_buf(); context.current_dir = dir.path().to_path_buf();
let expected = String::from("\n"); let expected = String::from("\n");
let actual = get_prompt(context); let actual = get_prompt(&context);
assert_eq!(expected, actual); assert_eq!(expected, actual);
dir.close() dir.close()
} }
+4 -4
View File
@@ -103,12 +103,12 @@ impl Segment {
let mut segs: Vec<Self> = Vec::new(); let mut segs: Vec<Self> = Vec::new();
value.into().split(LINE_TERMINATOR).for_each(|s| { value.into().split(LINE_TERMINATOR).for_each(|s| {
if !segs.is_empty() { if !segs.is_empty() {
segs.push(Self::LineTerm) segs.push(Self::LineTerm);
} }
segs.push(Self::Text(TextSegment { segs.push(Self::Text(TextSegment {
value: String::from(s), value: String::from(s),
style, style,
})) }));
}); });
segs segs
} }
@@ -136,12 +136,12 @@ impl Segment {
match self { match self {
Self::Fill(fs) => { Self::Fill(fs) => {
if fs.style.is_none() { if fs.style.is_none() {
fs.style = style fs.style = style;
} }
} }
Self::Text(ts) => { Self::Text(ts) => {
if ts.style.is_none() { if ts.style.is_none() {
ts.style = style ts.style = style;
} }
} }
Self::LineTerm => {} Self::LineTerm => {}
+1 -1
View File
@@ -398,7 +398,7 @@ mod test {
let deserializer = ValueDeserializer::new(&value); let deserializer = ValueDeserializer::new(&value);
let result = StarshipRootConfig::deserialize(deserializer); let result = StarshipRootConfig::deserialize(deserializer);
assert!(result.is_ok()) assert!(result.is_ok());
} }
#[test] #[test]
+5 -4
View File
@@ -1,4 +1,5 @@
use crate::context::{Context, Shell, Target}; use crate::context::{Context, Properties, Shell, Target};
use crate::context_env::Env;
use crate::logger::StarshipLogger; use crate::logger::StarshipLogger;
use crate::{ use crate::{
config::StarshipConfig, config::StarshipConfig,
@@ -37,12 +38,12 @@ fn init_logger() {
pub fn default_context() -> Context<'static> { pub fn default_context() -> Context<'static> {
let mut context = Context::new_with_shell_and_path( let mut context = Context::new_with_shell_and_path(
Default::default(), Properties::default(),
Shell::Unknown, Shell::Unknown,
Target::Main, Target::Main,
PathBuf::new(), PathBuf::new(),
PathBuf::new(), PathBuf::new(),
Default::default(), Env::default(),
); );
context.config = StarshipConfig { config: None }; context.config = StarshipConfig { config: None };
context context
@@ -168,7 +169,7 @@ impl<'a> ModuleRenderer<'a> {
/// Renders the module returning its output /// Renders the module returning its output
pub fn collect(self) -> Option<String> { pub fn collect(self) -> Option<String> {
let ret = crate::print::get_module(self.name, self.context); let ret = crate::print::get_module(self.name, &self.context);
// all tests rely on the fact that an empty module produces None as output as the // all tests rely on the fact that an empty module produces None as output as the
// convention was that there would be no module but None. This is nowadays not anymore // convention was that there would be no module but None. This is nowadays not anymore
// the case (to get durations for all modules). So here we make it so, that an empty // the case (to get durations for all modules). So here we make it so, that an empty
+22 -30
View File
@@ -43,7 +43,7 @@ pub fn read_file<P: AsRef<Path> + Debug>(file_name: P) -> Result<String> {
log::debug!("Error reading file: {result:?}"); log::debug!("Error reading file: {result:?}");
} else { } else {
log::trace!("File read successfully"); log::trace!("File read successfully");
}; }
result result
} }
@@ -291,10 +291,12 @@ Elixir 1.10 (compiled with Erlang/OTP 22)\n",
stdout: String::from("topic-branch"), stdout: String::from("topic-branch"),
stderr: String::default(), stderr: String::default(),
}), }),
"fossil branch new topic-branch trunk" => Some(CommandOutput { "fossil branch new topic-branch trunk" | "fossil update topic-branch" => {
Some(CommandOutput {
stdout: String::default(), stdout: String::default(),
stderr: String::default(), stderr: String::default(),
}), })
}
"fossil diff -i --numstat" => Some(CommandOutput { "fossil diff -i --numstat" => Some(CommandOutput {
stdout: String::from( stdout: String::from(
"\ "\
@@ -303,10 +305,6 @@ Elixir 1.10 (compiled with Erlang/OTP 22)\n",
), ),
stderr: String::default(), stderr: String::default(),
}), }),
"fossil update topic-branch" => Some(CommandOutput {
stdout: String::default(),
stderr: String::default(),
}),
"gleam --version" => Some(CommandOutput { "gleam --version" => Some(CommandOutput {
stdout: String::from("gleam 1.0.0\n"), stdout: String::from("gleam 1.0.0\n"),
stderr: String::default(), stderr: String::default(),
@@ -774,19 +772,13 @@ impl PathExt for Path {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
fn device_id(&self) -> Option<u64> { fn device_id(&self) -> Option<u64> {
use std::os::linux::fs::MetadataExt; use std::os::linux::fs::MetadataExt;
match self.metadata() { Some(self.metadata().ok()?.st_dev())
Ok(m) => Some(m.st_dev()),
Err(_) => None,
}
} }
#[cfg(all(unix, not(target_os = "linux")))] #[cfg(all(unix, not(target_os = "linux")))]
fn device_id(&self) -> Option<u64> { fn device_id(&self) -> Option<u64> {
use std::os::unix::fs::MetadataExt; use std::os::unix::fs::MetadataExt;
match self.metadata() { Some(self.metadata().ok()?.dev())
Ok(m) => Some(m.dev()),
Err(_) => None,
}
} }
} }
@@ -796,35 +788,35 @@ mod tests {
#[test] #[test]
fn render_time_test_0ms() { fn render_time_test_0ms() {
assert_eq!(render_time(0_u128, true), "0ms") assert_eq!(render_time(0_u128, true), "0ms");
} }
#[test] #[test]
fn render_time_test_0s() { fn render_time_test_0s() {
assert_eq!(render_time(0_u128, false), "0s") assert_eq!(render_time(0_u128, false), "0s");
} }
#[test] #[test]
fn render_time_test_500ms() { fn render_time_test_500ms() {
assert_eq!(render_time(500_u128, true), "500ms") assert_eq!(render_time(500_u128, true), "500ms");
} }
#[test] #[test]
fn render_time_test_500ms_no_millis() { fn render_time_test_500ms_no_millis() {
assert_eq!(render_time(500_u128, false), "0s") assert_eq!(render_time(500_u128, false), "0s");
} }
#[test] #[test]
fn render_time_test_10s() { fn render_time_test_10s() {
assert_eq!(render_time(10_000_u128, true), "10s0ms") assert_eq!(render_time(10_000_u128, true), "10s0ms");
} }
#[test] #[test]
fn render_time_test_90s() { fn render_time_test_90s() {
assert_eq!(render_time(90_000_u128, true), "1m30s0ms") assert_eq!(render_time(90_000_u128, true), "1m30s0ms");
} }
#[test] #[test]
fn render_time_test_10110s() { fn render_time_test_10110s() {
assert_eq!(render_time(10_110_000_u128, true), "2h48m30s0ms") assert_eq!(render_time(10_110_000_u128, true), "2h48m30s0ms");
} }
#[test] #[test]
fn render_time_test_1d() { fn render_time_test_1d() {
assert_eq!(render_time(86_400_000_u128, false), "1d0h0m0s") assert_eq!(render_time(86_400_000_u128, false), "1d0h0m0s");
} }
#[test] #[test]
@@ -839,7 +831,7 @@ mod tests {
stderr: String::from("stderr ok!\n"), stderr: String::from("stderr ok!\n"),
}); });
assert_eq!(result, expected) assert_eq!(result, expected);
} }
// While the exec_cmd should work on Windows some of these tests assume a Unix-like // While the exec_cmd should work on Windows some of these tests assume a Unix-like
@@ -854,7 +846,7 @@ mod tests {
stderr: String::new(), stderr: String::new(),
}); });
assert_eq!(result, expected) assert_eq!(result, expected);
} }
#[test] #[test]
@@ -867,7 +859,7 @@ mod tests {
stderr: String::new(), stderr: String::new(),
}); });
assert_eq!(result, expected) assert_eq!(result, expected);
} }
#[test] #[test]
@@ -883,7 +875,7 @@ mod tests {
stderr: String::from("hello\n"), stderr: String::from("hello\n"),
}); });
assert_eq!(result, expected) assert_eq!(result, expected);
} }
#[test] #[test]
@@ -899,7 +891,7 @@ mod tests {
stderr: String::from("world\n"), stderr: String::from("world\n"),
}); });
assert_eq!(result, expected) assert_eq!(result, expected);
} }
#[test] #[test]
@@ -908,7 +900,7 @@ mod tests {
let result = internal_exec_cmd("false", &[] as &[&OsStr], Duration::from_millis(500)); let result = internal_exec_cmd("false", &[] as &[&OsStr], Duration::from_millis(500));
let expected = None; let expected = None;
assert_eq!(result, expected) assert_eq!(result, expected);
} }
#[test] #[test]
@@ -917,7 +909,7 @@ mod tests {
let result = internal_exec_cmd("sleep", &["500"], Duration::from_millis(500)); let result = internal_exec_cmd("sleep", &["500"], Duration::from_millis(500));
let expected = None; let expected = None;
assert_eq!(result, expected) assert_eq!(result, expected);
} }
#[test] #[test]