diff options
author | Clement Tsang <34804052+ClementTsang@users.noreply.github.com> | 2023-06-23 07:42:16 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-23 03:42:16 -0400 |
commit | cc3833289fa5063efe30c2a16da56a9b04117e1b (patch) | |
tree | 5408634129744b9f613f11f35da1b04a07586f0b | |
parent | 0b7f4c745dbf5ef93a0d1fbf185fd725995a74bb (diff) |
feature: support human times for rate (#1221)
-rw-r--r-- | CHANGELOG.md | 4 | ||||
-rw-r--r-- | src/app.rs | 2 | ||||
-rw-r--r-- | src/args.rs | 4 | ||||
-rw-r--r-- | src/constants.rs | 2 | ||||
-rw-r--r-- | src/lib.rs | 2 | ||||
-rw-r--r-- | src/options.rs | 102 | ||||
-rw-r--r-- | tests/arg_tests.rs | 2 |
7 files changed, 65 insertions, 53 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 86841312..67f0c462 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#1216](https://github.com/ClementTsang/bottom/pull/1216): Fix arguments not being sorted alphabetically. - [#1219](https://github.com/ClementTsang/bottom/pull/1219): Fix overflow/underflow in graph timespan zoom. +## Features + +- [#1221](https://github.com/ClementTsang/bottom/pull/1221): Support human times for `rate`. + ## [0.9.2] - 2023-06-11 ## Bug Fixes @@ -45,7 +45,7 @@ pub enum AxisScaling { /// by config files or launch options. #[derive(Debug, Default, Eq, PartialEq)] pub struct AppConfigFields { - pub update_rate_in_milliseconds: u64, + pub update_rate: u64, pub temperature_type: temperature::TemperatureType, pub use_dot: bool, pub left_legend: bool, diff --git a/src/args.rs b/src/args.rs index 87035a6a..b384acc0 100644 --- a/src/args.rs +++ b/src/args.rs @@ -353,8 +353,8 @@ use CPU (3) as the default instead. .long("rate") .action(ArgAction::Set) .value_name("MS") - .help("Sets a refresh rate in ms.") - .long_help("Sets a refresh rate in milliseconds. The minimum is 250ms, and defaults to 1000ms. Smaller values may take more computer resources."); + .help("Sets the data refresh rate.") + .long_help("Sets the data refresh rate. The minimum is 250ms, and defaults to 1000ms. Smaller values may take more computer resources."); let time_delta = Arg::new("time_delta") .short('d') diff --git a/src/constants.rs b/src/constants.rs index a76c8609..9a0cd04a 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -520,7 +520,7 @@ pub const CONFIG_TEXT: &str = r##"# This is a default config file for bottom. A # Whether to use dot markers rather than braille. #dot_marker = false # The update rate of the application. -#rate = 1000 +#rate = "1s" # Whether to put the CPU legend to the left. #left_legend = false # Whether to set CPU% on a process to be based on the total CPU or just current usage. @@ -484,7 +484,7 @@ pub fn create_collection_thread( let use_current_cpu_total = app_config_fields.use_current_cpu_total; let unnormalized_cpu = app_config_fields.unnormalized_cpu; let show_average_cpu = app_config_fields.show_average_cpu; - let update_time = app_config_fields.update_rate_in_milliseconds; + let update_time = app_config_fields.update_rate; thread::spawn(move || { let mut data_state = data_harvester::DataCollector::new(filters); diff --git a/src/options.rs b/src/options.rs index 4a4d15f5..412748a6 100644 --- a/src/options.rs +++ b/src/options.rs @@ -66,45 +66,45 @@ impl From<u64> for StringOrNum { #[derive(Clone, Debug, Default, Deserialize, Serialize)] pub struct ConfigFlags { - pub hide_avg_cpu: Option<bool>, - pub dot_marker: Option<bool>, - pub temperature_type: Option<String>, - pub rate: Option<u64>, - pub left_legend: Option<bool>, - pub current_usage: Option<bool>, - pub unnormalized_cpu: Option<bool>, - pub group_processes: Option<bool>, - pub case_sensitive: Option<bool>, - pub whole_word: Option<bool>, - pub regex: Option<bool>, - pub basic: Option<bool>, + hide_avg_cpu: Option<bool>, + dot_marker: Option<bool>, + temperature_type: Option<String>, + rate: Option<StringOrNum>, + left_legend: Option<bool>, + current_usage: Option<bool>, + unnormalized_cpu: Option<bool>, + group_processes: Option<bool>, + case_sensitive: Option<bool>, + whole_word: Option<bool>, + regex: Option<bool>, + basic: Option<bool>, default_time_value: Option<StringOrNum>, time_delta: Option<StringOrNum>, - pub autohide_time: Option<bool>, - pub hide_time: Option<bool>, - pub default_widget_type: Option<String>, - pub default_widget_count: Option<u64>, - pub expanded_on_startup: Option<bool>, - pub use_old_network_legend: Option<bool>, - pub hide_table_gap: Option<bool>, - pub battery: Option<bool>, - pub disable_click: Option<bool>, - pub no_write: Option<bool>, + autohide_time: Option<bool>, + hide_time: Option<bool>, + default_widget_type: Option<String>, + default_widget_count: Option<u64>, + expanded_on_startup: Option<bool>, + use_old_network_legend: Option<bool>, + hide_table_gap: Option<bool>, + battery: Option<bool>, + disable_click: Option<bool>, + no_write: Option<bool>, /// For built-in colour palettes. - pub color: Option<String>, - pub mem_as_value: Option<bool>, - pub tree: Option<bool>, + color: Option<String>, + mem_as_value: Option<bool>, + tree: Option<bool>, show_table_scroll_position: Option<bool>, - pub process_command: Option<bool>, - pub disable_advanced_kill: Option<bool>, - pub network_use_bytes: Option<bool>, - pub network_use_log: Option<bool>, - pub network_use_binary_prefix: Option<bool>, - pub enable_gpu_memory: Option<bool>, - pub enable_cache_memory: Option<bool>, + process_command: Option<bool>, + disable_advanced_kill: Option<bool>, + network_use_bytes: Option<bool>, + network_use_log: Option<bool>, + network_use_binary_prefix: Option<bool>, + enable_gpu_memory: Option<bool>, + enable_cache_memory: Option<bool>, #[serde(with = "humantime_serde")] #[serde(default)] - pub retention: Option<Duration>, + retention: Option<Duration>, } #[derive(Clone, Debug, Default, Deserialize, Serialize)] @@ -262,7 +262,7 @@ pub fn build_app( }; let app_config_fields = AppConfigFields { - update_rate_in_milliseconds: get_update_rate_in_milliseconds(matches, config) + update_rate: get_update_rate(matches, config) .context("Update 'rate' in your config file.")?, temperature_type: get_temperature(matches, config) .context("Update 'temperature_type' in your config file.")?, @@ -549,16 +549,15 @@ pub fn get_widget_layout( Ok((bottom_layout, default_widget_id, default_widget_type)) } -fn get_update_rate_in_milliseconds(matches: &ArgMatches, config: &Config) -> error::Result<u64> { - let update_rate_in_milliseconds = if let Some(update_rate) = matches.get_one::<String>("rate") { - update_rate.parse::<u64>().map_err(|_| { - BottomError::ConfigError( - "could not parse as a valid 64-bit unsigned integer".to_string(), - ) - })? +fn get_update_rate(matches: &ArgMatches, config: &Config) -> error::Result<u64> { + let update_rate = if let Some(update_rate) = matches.get_one::<String>("rate") { + try_parse_ms(update_rate)? } else if let Some(flags) = &config.flags { - if let Some(rate) = flags.rate { - rate + if let Some(rate) = &flags.rate { + match rate { + StringOrNum::String(s) => try_parse_ms(s)?, + StringOrNum::Num(n) => *n, + } } else { DEFAULT_REFRESH_RATE_IN_MILLISECONDS } @@ -566,13 +565,13 @@ fn get_update_rate_in_milliseconds(matches: &ArgMatches, config: &Config) -> err DEFAULT_REFRESH_RATE_IN_MILLISECONDS }; - if update_rate_in_milliseconds < 250 { + if update_rate < 250 { return Err(BottomError::ConfigError( - "set your update rate to be at least 250 milliseconds.".to_string(), + "set your update rate to be at least 250 ms.".to_string(), )); } - Ok(update_rate_in_milliseconds) + Ok(update_rate) } fn get_temperature( @@ -914,7 +913,7 @@ mod test { use crate::{ app::App, canvas::canvas_styling::CanvasStyling, - options::{get_default_time_value, try_parse_ms, ConfigFlags}, + options::{get_default_time_value, get_update_rate, try_parse_ms, ConfigFlags}, }; #[test] @@ -999,6 +998,7 @@ mod test { let flags = ConfigFlags { time_delta: Some("2 min".to_string().into()), default_time_value: Some("300s".to_string().into()), + rate: Some("1s".to_string().into()), ..Default::default() }; @@ -1013,6 +1013,8 @@ mod test { get_default_time_value(&matches, &config, 60 * 60 * 1000), Ok(5 * 60 * 1000) ); + + assert_eq!(get_update_rate(&matches, &config), Ok(1000)); } #[test] @@ -1024,6 +1026,7 @@ mod test { let flags = ConfigFlags { time_delta: Some("120000".to_string().into()), default_time_value: Some("300000".to_string().into()), + rate: Some("1000".to_string().into()), ..Default::default() }; @@ -1038,6 +1041,8 @@ mod test { get_default_time_value(&matches, &config, 60 * 60 * 1000), Ok(5 * 60 * 1000) ); + + assert_eq!(get_update_rate(&matches, &config), Ok(1000)); } #[test] @@ -1049,6 +1054,7 @@ mod test { let flags = ConfigFlags { time_delta: Some(120000.into()), default_time_value: Some(300000.into()), + rate: Some(1000.into()), ..Default::default() }; @@ -1063,6 +1069,8 @@ mod test { get_default_time_value(&matches, &config, 60 * 60 * 1000), Ok(5 * 60 * 1000) ); + + assert_eq!(get_update_rate(&matches, &config), Ok(1000)); } fn create_app(config: Config, matches: ArgMatches) -> App { diff --git a/tests/arg_tests.rs b/tests/arg_tests.rs index 0bbddce8..c233c14e 100644 --- a/tests/arg_tests.rs +++ b/tests/arg_tests.rs @@ -15,7 +15,7 @@ fn test_small_rate() { .assert() .failure() .stderr(predicate::str::contains( - "set your update rate to be at least 250 milliseconds.", + "set your update rate to be at least 250 ms.", )); } |