Cleanup before modularity (#84)

* Uptick some crates, update README dependencies

* Cleanup before modularity feature.

* Fix missing reset zoom on reset

* Fixed reset... not resetting search or data displayed

* Cleaned up options a tiny bit to make more sense.

* Cleaned up some TODOs and the like.

* specify only build master branch.
This commit is contained in:
Clement Tsang 2020-03-13 01:07:24 -04:00 committed by GitHub
parent d9747f78e8
commit 1968bb14b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 326 additions and 290 deletions

View File

@ -11,6 +11,9 @@ jobs:
- rust: nightly - rust: nightly
- env: TARGET=x86_64-pc-windows-gnu # Seems to cause problems. TODO: Add test for it, but keep allow fail. - env: TARGET=x86_64-pc-windows-gnu # Seems to cause problems. TODO: Add test for it, but keep allow fail.
fast_finish: true fast_finish: true
branches:
only:
- master
before_install: before_install:
- export RUST_BACKTRACE=1 - export RUST_BACKTRACE=1

View File

@ -23,7 +23,8 @@ lto = "fat"
codegen-units = 1 codegen-units = 1
[dependencies] [dependencies]
chrono = "0.4.10" crossterm = "0.16"
chrono = "0.4.11"
clap = "2.33.0" clap = "2.33.0"
dirs = "2.0.2" dirs = "2.0.2"
fern = "0.6.0" fern = "0.6.0"
@ -32,11 +33,11 @@ heim = "0.0.10"
log = "0.4.8" log = "0.4.8"
regex = "1.3.4" regex = "1.3.4"
sysinfo = "0.11" sysinfo = "0.11"
crossterm = "0.16" toml = "0.5.6"
tui = {version = "0.8", features = ["crossterm"], default-features = false } tui = {version = "0.8", features = ["crossterm"], default-features = false }
typed-builder = "0.5.1"
lazy_static = "1.4.0" lazy_static = "1.4.0"
backtrace = "0.3" backtrace = "0.3"
toml = "0.5.6"
serde = {version = "1.0", features = ["derive"] } serde = {version = "1.0", features = ["derive"] }
unicode-segmentation = "1.6.0" unicode-segmentation = "1.6.0"
unicode-width = "0.1.7" unicode-width = "0.1.7"

View File

@ -42,7 +42,7 @@ For information about config files, see [this document](./docs/config.md) for mo
## Installation ## Installation
In all cases you can install the in-development version by cloning from this repo and using `cargo build --release`. This is built and tested with Rust Stable (1.41 as of writing). In all cases you can install the in-development version by cloning from this repo and using `cargo build --release`. This is built and tested with Rust Stable (1.42 as of writing).
In addition to the below methods, you can manually build from the [Releases](https://github.com/ClementTsang/bottom/releases) page by downloading and building. In addition to the below methods, you can manually build from the [Releases](https://github.com/ClementTsang/bottom/releases) page by downloading and building.
@ -257,13 +257,13 @@ Thanks to those who have contributed:
- [dirs](https://github.com/soc/dirs-rs) - [dirs](https://github.com/soc/dirs-rs)
- [fern](https://github.com/daboross/fern) - [fern](https://github.com/daboross/fern)
- [futures-rs](https://github.com/rust-lang-nursery/futures-rs) - [futures-rs](https://github.com/rust-lang-nursery/futures-rs)
- [futures-timer](https://github.com/rustasync/futures-timer)
- [heim](https://github.com/heim-rs/heim) - [heim](https://github.com/heim-rs/heim)
- [lazy_static](https://github.com/rust-lang-nursery/lazy-static.rs) - [lazy_static](https://github.com/rust-lang-nursery/lazy-static.rs)
- [log](https://github.com/rust-lang-nursery/log) - [log](https://github.com/rust-lang-nursery/log)
- [serde](https://github.com/serde-rs/serde)
- [sysinfo](https://github.com/GuillaumeGomez/sysinfo) - [sysinfo](https://github.com/GuillaumeGomez/sysinfo)
- [tokio](https://github.com/tokio-rs/tokio)
- [toml-rs](https://github.com/alexcrichton/toml-rs) - [toml-rs](https://github.com/alexcrichton/toml-rs)
- [typed-builder](https://github.com/idanarye/rust-typed-builder)
- [tui-rs](https://github.com/fdehau/tui-rs) - [tui-rs](https://github.com/fdehau/tui-rs)
- [unicode-segmentation](https://github.com/unicode-rs/unicode-segmentation) - [unicode-segmentation](https://github.com/unicode-rs/unicode-segmentation)
- [unicode-width](https://github.com/unicode-rs/unicode-width) - [unicode-width](https://github.com/unicode-rs/unicode-width)

View File

@ -4,6 +4,8 @@ use std::time::Instant;
use unicode_segmentation::GraphemeCursor; use unicode_segmentation::GraphemeCursor;
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr}; use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
use typed_builder::*;
use data_farmer::*; use data_farmer::*;
use data_harvester::{processes, temperature}; use data_harvester::{processes, temperature};
@ -108,8 +110,8 @@ impl Default for AppScrollState {
/// AppSearchState deals with generic searching (I might do this in the future). /// AppSearchState deals with generic searching (I might do this in the future).
pub struct AppSearchState { pub struct AppSearchState {
pub is_enabled: bool, pub is_enabled: bool,
current_search_query: String, pub current_search_query: String,
current_regex: Option<std::result::Result<regex::Regex, regex::Error>>, pub current_regex: Option<std::result::Result<regex::Regex, regex::Error>>,
pub is_blank_search: bool, pub is_blank_search: bool,
pub is_invalid_search: bool, pub is_invalid_search: bool,
pub grapheme_cursor: GraphemeCursor, pub grapheme_cursor: GraphemeCursor,
@ -137,10 +139,11 @@ impl Default for AppSearchState {
impl AppSearchState { impl AppSearchState {
/// Returns a reset but still enabled app search state /// Returns a reset but still enabled app search state
pub fn reset() -> Self { pub fn reset(&mut self) {
let mut app_search_state = AppSearchState::default(); *self = AppSearchState {
app_search_state.is_enabled = true; is_enabled: self.is_enabled,
app_search_state ..AppSearchState::default()
}
} }
pub fn is_invalid_or_blank_search(&self) -> bool { pub fn is_invalid_or_blank_search(&self) -> bool {
@ -211,7 +214,6 @@ impl Default for AppHelpDialogState {
/// AppConfigFields is meant to cover basic fields that would normally be set /// AppConfigFields is meant to cover basic fields that would normally be set
/// by config files or launch options. /// by config files or launch options.
#[derive(Default)]
pub struct AppConfigFields { pub struct AppConfigFields {
pub update_rate_in_milliseconds: u64, pub update_rate_in_milliseconds: u64,
pub temperature_type: temperature::TemperatureType, pub temperature_type: temperature::TemperatureType,
@ -233,21 +235,21 @@ pub struct NetState {
pub is_showing_rx: bool, pub is_showing_rx: bool,
pub is_showing_tx: bool, pub is_showing_tx: bool,
pub zoom_level: f64, pub zoom_level: f64,
pub display_time: u64, pub current_display_time: u64,
pub force_update: bool, pub force_update: bool,
pub display_time_instant: Option<Instant>, pub autohide_timer: Option<Instant>,
} }
impl Default for NetState { impl NetState {
fn default() -> Self { pub fn init(current_display_time: u64, autohide_timer: Option<Instant>) -> Self {
NetState { NetState {
is_showing_tray: false, is_showing_tray: false,
is_showing_rx: true, is_showing_rx: true,
is_showing_tx: true, is_showing_tx: true,
zoom_level: 100.0, zoom_level: 100.0,
display_time: constants::DEFAULT_TIME_MILLISECONDS, current_display_time,
force_update: false, force_update: false,
display_time_instant: None, autohide_timer,
} }
} }
} }
@ -258,21 +260,21 @@ pub struct CpuState {
pub zoom_level: f64, pub zoom_level: f64,
pub core_show_vec: Vec<bool>, pub core_show_vec: Vec<bool>,
pub num_cpus_shown: u64, pub num_cpus_shown: u64,
pub display_time: u64, pub current_display_time: u64,
pub force_update: bool, pub force_update: bool,
pub display_time_instant: Option<Instant>, pub autohide_timer: Option<Instant>,
} }
impl Default for CpuState { impl CpuState {
fn default() -> Self { pub fn init(current_display_time: u64, autohide_timer: Option<Instant>) -> Self {
CpuState { CpuState {
is_showing_tray: false, is_showing_tray: false,
zoom_level: 100.0, zoom_level: 100.0,
core_show_vec: Vec::new(), core_show_vec: Vec::new(),
num_cpus_shown: 0, num_cpus_shown: 0,
display_time: constants::DEFAULT_TIME_MILLISECONDS, current_display_time,
force_update: false, force_update: false,
display_time_instant: None, autohide_timer,
} }
} }
} }
@ -283,136 +285,117 @@ pub struct MemState {
pub is_showing_ram: bool, pub is_showing_ram: bool,
pub is_showing_swap: bool, pub is_showing_swap: bool,
pub zoom_level: f64, pub zoom_level: f64,
pub display_time: u64, pub current_display_time: u64,
pub force_update: bool, pub force_update: bool,
pub display_time_instant: Option<Instant>, pub autohide_timer: Option<Instant>,
} }
impl Default for MemState { impl MemState {
fn default() -> Self { pub fn init(current_display_time: u64, autohide_timer: Option<Instant>) -> Self {
MemState { MemState {
is_showing_tray: false, is_showing_tray: false,
is_showing_ram: true, is_showing_ram: true,
is_showing_swap: true, is_showing_swap: true,
zoom_level: 100.0, zoom_level: 100.0,
display_time: constants::DEFAULT_TIME_MILLISECONDS, current_display_time,
force_update: false, force_update: false,
display_time_instant: None, autohide_timer,
} }
} }
} }
#[derive(TypedBuilder)]
pub struct App { pub struct App {
#[builder(default=processes::ProcessSorting::CPU, setter(skip))]
pub process_sorting_type: processes::ProcessSorting, pub process_sorting_type: processes::ProcessSorting,
#[builder(default = true, setter(skip))]
pub process_sorting_reverse: bool, pub process_sorting_reverse: bool,
#[builder(default = false, setter(skip))]
pub force_update_processes: bool, pub force_update_processes: bool,
#[builder(default, setter(skip))]
pub app_scroll_positions: AppScrollState, pub app_scroll_positions: AppScrollState,
pub current_widget_selected: WidgetPosition,
pub previous_basic_table_selected: WidgetPosition, #[builder(default = false, setter(skip))]
awaiting_second_char: bool, awaiting_second_char: bool,
#[builder(default, setter(skip))]
second_char: Option<char>, second_char: Option<char>,
#[builder(default, setter(skip))]
pub dd_err: Option<String>, pub dd_err: Option<String>,
#[builder(default, setter(skip))]
to_delete_process_list: Option<(String, Vec<u32>)>, to_delete_process_list: Option<(String, Vec<u32>)>,
#[builder(default = false, setter(skip))]
pub is_frozen: bool, pub is_frozen: bool,
#[builder(default = Instant::now(), setter(skip))]
last_key_press: Instant, last_key_press: Instant,
#[builder(default, setter(skip))]
pub canvas_data: canvas::DisplayableData, pub canvas_data: canvas::DisplayableData,
#[builder(default = false)]
enable_grouping: bool, enable_grouping: bool,
#[builder(default, setter(skip))]
pub data_collection: DataCollection, pub data_collection: DataCollection,
#[builder(default, setter(skip))]
pub process_search_state: ProcessSearchState, pub process_search_state: ProcessSearchState,
#[builder(default, setter(skip))]
pub delete_dialog_state: AppDeleteDialogState, pub delete_dialog_state: AppDeleteDialogState,
#[builder(default, setter(skip))]
pub help_dialog_state: AppHelpDialogState, pub help_dialog_state: AppHelpDialogState,
pub app_config_fields: AppConfigFields,
#[builder(default = false, setter(skip))]
pub is_expanded: bool, pub is_expanded: bool,
#[builder(default = false, setter(skip))]
pub is_resized: bool, pub is_resized: bool,
pub cpu_state: CpuState, pub cpu_state: CpuState,
pub mem_state: MemState, pub mem_state: MemState,
pub net_state: NetState, pub net_state: NetState,
pub app_config_fields: AppConfigFields,
pub current_widget_selected: WidgetPosition,
pub previous_basic_table_selected: WidgetPosition,
} }
impl App { impl App {
#[allow(clippy::too_many_arguments)]
// TODO: [REFACTOR] use builder pattern instead.
pub fn new(
show_average_cpu: bool, temperature_type: temperature::TemperatureType,
update_rate_in_milliseconds: u64, use_dot: bool, left_legend: bool,
use_current_cpu_total: bool, current_widget_selected: WidgetPosition,
show_disabled_data: bool, use_basic_mode: bool, default_time_value: u64,
time_interval: u64,
) -> App {
let mut cpu_state = CpuState::default();
let mut mem_state = MemState::default();
let mut net_state = NetState::default();
cpu_state.display_time = default_time_value;
mem_state.display_time = default_time_value;
net_state.display_time = default_time_value;
App {
process_sorting_type: processes::ProcessSorting::CPU,
process_sorting_reverse: true,
force_update_processes: false,
current_widget_selected: if use_basic_mode {
match current_widget_selected {
WidgetPosition::Cpu => WidgetPosition::BasicCpu,
WidgetPosition::Network => WidgetPosition::BasicNet,
WidgetPosition::Mem => WidgetPosition::BasicMem,
_ => current_widget_selected,
}
} else {
current_widget_selected
},
previous_basic_table_selected: if current_widget_selected.is_widget_table() {
current_widget_selected
} else {
WidgetPosition::Process
},
app_scroll_positions: AppScrollState::default(),
awaiting_second_char: false,
second_char: None,
dd_err: None,
to_delete_process_list: None,
is_frozen: false,
last_key_press: Instant::now(),
canvas_data: canvas::DisplayableData::default(),
enable_grouping: false,
data_collection: DataCollection::default(),
process_search_state: ProcessSearchState::default(),
delete_dialog_state: AppDeleteDialogState::default(),
help_dialog_state: AppHelpDialogState::default(),
app_config_fields: AppConfigFields {
show_average_cpu,
temperature_type,
use_dot,
update_rate_in_milliseconds,
left_legend,
use_current_cpu_total,
show_disabled_data,
use_basic_mode,
default_time_value,
time_interval,
hide_time: false,
autohide_time: false,
},
is_expanded: false,
is_resized: false,
cpu_state,
mem_state,
net_state,
}
}
pub fn reset(&mut self) { pub fn reset(&mut self) {
// Reset multi
self.reset_multi_tap_keys(); self.reset_multi_tap_keys();
// Reset dialog state
self.help_dialog_state.is_showing_help = false; self.help_dialog_state.is_showing_help = false;
self.delete_dialog_state.is_showing_dd = false; self.delete_dialog_state.is_showing_dd = false;
if self.process_search_state.search_state.is_enabled {
self.current_widget_selected = WidgetPosition::Process; // Close search and reset it
self.process_search_state.search_state.is_enabled = false; self.process_search_state.search_state.reset();
} self.force_update_processes = true;
self.process_search_state.search_state.current_search_query = String::new();
self.process_search_state.is_searching_with_pid = false; // Clear current delete list
self.to_delete_process_list = None; self.to_delete_process_list = None;
self.dd_err = None; self.dd_err = None;
// Unfreeze.
self.is_frozen = false;
// Reset zoom
self.reset_cpu_zoom();
self.reset_mem_zoom();
self.reset_net_zoom();
// Reset data
self.data_collection.reset();
} }
pub fn on_esc(&mut self) { pub fn on_esc(&mut self) {
@ -783,7 +766,7 @@ impl App {
pub fn clear_search(&mut self) { pub fn clear_search(&mut self) {
if let WidgetPosition::ProcessSearch = self.current_widget_selected { if let WidgetPosition::ProcessSearch = self.current_widget_selected {
self.force_update_processes = true; self.force_update_processes = true;
self.process_search_state.search_state = AppSearchState::reset(); self.process_search_state.search_state.reset();
} }
} }
@ -795,7 +778,7 @@ impl App {
&self.process_search_state.search_state.current_search_query[start_position..], &self.process_search_state.search_state.current_search_query[start_position..],
start_position, start_position,
) )
.unwrap(); // TODO: [UNWRAP] unwrap in this and walk_back seem sketch .unwrap();
} }
pub fn search_walk_back(&mut self, start_position: usize) { pub fn search_walk_back(&mut self, start_position: usize) {
@ -1544,50 +1527,53 @@ impl App {
fn zoom_out(&mut self) { fn zoom_out(&mut self) {
match self.current_widget_selected { match self.current_widget_selected {
WidgetPosition::Cpu => { WidgetPosition::Cpu => {
let new_time = self.cpu_state.display_time + self.app_config_fields.time_interval; let new_time =
self.cpu_state.current_display_time + self.app_config_fields.time_interval;
if new_time <= constants::STALE_MAX_MILLISECONDS { if new_time <= constants::STALE_MAX_MILLISECONDS {
self.cpu_state.display_time = new_time; self.cpu_state.current_display_time = new_time;
self.cpu_state.force_update = true; self.cpu_state.force_update = true;
if self.app_config_fields.autohide_time { if self.app_config_fields.autohide_time {
self.cpu_state.display_time_instant = Some(Instant::now()); self.cpu_state.autohide_timer = Some(Instant::now());
} }
} else if self.cpu_state.display_time != constants::STALE_MAX_MILLISECONDS { } else if self.cpu_state.current_display_time != constants::STALE_MAX_MILLISECONDS {
self.cpu_state.display_time = constants::STALE_MAX_MILLISECONDS; self.cpu_state.current_display_time = constants::STALE_MAX_MILLISECONDS;
self.cpu_state.force_update = true; self.cpu_state.force_update = true;
if self.app_config_fields.autohide_time { if self.app_config_fields.autohide_time {
self.cpu_state.display_time_instant = Some(Instant::now()); self.cpu_state.autohide_timer = Some(Instant::now());
} }
} }
} }
WidgetPosition::Mem => { WidgetPosition::Mem => {
let new_time = self.mem_state.display_time + self.app_config_fields.time_interval; let new_time =
self.mem_state.current_display_time + self.app_config_fields.time_interval;
if new_time <= constants::STALE_MAX_MILLISECONDS { if new_time <= constants::STALE_MAX_MILLISECONDS {
self.mem_state.display_time = new_time; self.mem_state.current_display_time = new_time;
self.mem_state.force_update = true; self.mem_state.force_update = true;
if self.app_config_fields.autohide_time { if self.app_config_fields.autohide_time {
self.mem_state.display_time_instant = Some(Instant::now()); self.mem_state.autohide_timer = Some(Instant::now());
} }
} else if self.mem_state.display_time != constants::STALE_MAX_MILLISECONDS { } else if self.mem_state.current_display_time != constants::STALE_MAX_MILLISECONDS {
self.mem_state.display_time = constants::STALE_MAX_MILLISECONDS; self.mem_state.current_display_time = constants::STALE_MAX_MILLISECONDS;
self.mem_state.force_update = true; self.mem_state.force_update = true;
if self.app_config_fields.autohide_time { if self.app_config_fields.autohide_time {
self.mem_state.display_time_instant = Some(Instant::now()); self.mem_state.autohide_timer = Some(Instant::now());
} }
} }
} }
WidgetPosition::Network => { WidgetPosition::Network => {
let new_time = self.net_state.display_time + self.app_config_fields.time_interval; let new_time =
self.net_state.current_display_time + self.app_config_fields.time_interval;
if new_time <= constants::STALE_MAX_MILLISECONDS { if new_time <= constants::STALE_MAX_MILLISECONDS {
self.net_state.display_time = new_time; self.net_state.current_display_time = new_time;
self.net_state.force_update = true; self.net_state.force_update = true;
if self.app_config_fields.autohide_time { if self.app_config_fields.autohide_time {
self.net_state.display_time_instant = Some(Instant::now()); self.net_state.autohide_timer = Some(Instant::now());
} }
} else if self.net_state.display_time != constants::STALE_MAX_MILLISECONDS { } else if self.net_state.current_display_time != constants::STALE_MAX_MILLISECONDS {
self.net_state.display_time = constants::STALE_MAX_MILLISECONDS; self.net_state.current_display_time = constants::STALE_MAX_MILLISECONDS;
self.net_state.force_update = true; self.net_state.force_update = true;
if self.app_config_fields.autohide_time { if self.app_config_fields.autohide_time {
self.net_state.display_time_instant = Some(Instant::now()); self.net_state.autohide_timer = Some(Instant::now());
} }
} }
} }
@ -1598,50 +1584,53 @@ impl App {
fn zoom_in(&mut self) { fn zoom_in(&mut self) {
match self.current_widget_selected { match self.current_widget_selected {
WidgetPosition::Cpu => { WidgetPosition::Cpu => {
let new_time = self.cpu_state.display_time - self.app_config_fields.time_interval; let new_time =
self.cpu_state.current_display_time - self.app_config_fields.time_interval;
if new_time >= constants::STALE_MIN_MILLISECONDS { if new_time >= constants::STALE_MIN_MILLISECONDS {
self.cpu_state.display_time = new_time; self.cpu_state.current_display_time = new_time;
self.cpu_state.force_update = true; self.cpu_state.force_update = true;
if self.app_config_fields.autohide_time { if self.app_config_fields.autohide_time {
self.cpu_state.display_time_instant = Some(Instant::now()); self.cpu_state.autohide_timer = Some(Instant::now());
} }
} else if self.cpu_state.display_time != constants::STALE_MIN_MILLISECONDS { } else if self.cpu_state.current_display_time != constants::STALE_MIN_MILLISECONDS {
self.cpu_state.display_time = constants::STALE_MIN_MILLISECONDS; self.cpu_state.current_display_time = constants::STALE_MIN_MILLISECONDS;
self.cpu_state.force_update = true; self.cpu_state.force_update = true;
if self.app_config_fields.autohide_time { if self.app_config_fields.autohide_time {
self.cpu_state.display_time_instant = Some(Instant::now()); self.cpu_state.autohide_timer = Some(Instant::now());
} }
} }
} }
WidgetPosition::Mem => { WidgetPosition::Mem => {
let new_time = self.mem_state.display_time - self.app_config_fields.time_interval; let new_time =
self.mem_state.current_display_time - self.app_config_fields.time_interval;
if new_time >= constants::STALE_MIN_MILLISECONDS { if new_time >= constants::STALE_MIN_MILLISECONDS {
self.mem_state.display_time = new_time; self.mem_state.current_display_time = new_time;
self.mem_state.force_update = true; self.mem_state.force_update = true;
if self.app_config_fields.autohide_time { if self.app_config_fields.autohide_time {
self.mem_state.display_time_instant = Some(Instant::now()); self.mem_state.autohide_timer = Some(Instant::now());
} }
} else if self.mem_state.display_time != constants::STALE_MIN_MILLISECONDS { } else if self.mem_state.current_display_time != constants::STALE_MIN_MILLISECONDS {
self.mem_state.display_time = constants::STALE_MIN_MILLISECONDS; self.mem_state.current_display_time = constants::STALE_MIN_MILLISECONDS;
self.mem_state.force_update = true; self.mem_state.force_update = true;
if self.app_config_fields.autohide_time { if self.app_config_fields.autohide_time {
self.mem_state.display_time_instant = Some(Instant::now()); self.mem_state.autohide_timer = Some(Instant::now());
} }
} }
} }
WidgetPosition::Network => { WidgetPosition::Network => {
let new_time = self.net_state.display_time - self.app_config_fields.time_interval; let new_time =
self.net_state.current_display_time - self.app_config_fields.time_interval;
if new_time >= constants::STALE_MIN_MILLISECONDS { if new_time >= constants::STALE_MIN_MILLISECONDS {
self.net_state.display_time = new_time; self.net_state.current_display_time = new_time;
self.net_state.force_update = true; self.net_state.force_update = true;
if self.app_config_fields.autohide_time { if self.app_config_fields.autohide_time {
self.net_state.display_time_instant = Some(Instant::now()); self.net_state.autohide_timer = Some(Instant::now());
} }
} else if self.net_state.display_time != constants::STALE_MIN_MILLISECONDS { } else if self.net_state.current_display_time != constants::STALE_MIN_MILLISECONDS {
self.net_state.display_time = constants::STALE_MIN_MILLISECONDS; self.net_state.current_display_time = constants::STALE_MIN_MILLISECONDS;
self.net_state.force_update = true; self.net_state.force_update = true;
if self.app_config_fields.autohide_time { if self.app_config_fields.autohide_time {
self.net_state.display_time_instant = Some(Instant::now()); self.net_state.autohide_timer = Some(Instant::now());
} }
} }
} }
@ -1649,29 +1638,35 @@ impl App {
} }
} }
fn reset_cpu_zoom(&mut self) {
self.cpu_state.current_display_time = self.app_config_fields.default_time_value;
self.cpu_state.force_update = true;
if self.app_config_fields.autohide_time {
self.cpu_state.autohide_timer = Some(Instant::now());
}
}
fn reset_mem_zoom(&mut self) {
self.mem_state.current_display_time = self.app_config_fields.default_time_value;
self.mem_state.force_update = true;
if self.app_config_fields.autohide_time {
self.mem_state.autohide_timer = Some(Instant::now());
}
}
fn reset_net_zoom(&mut self) {
self.net_state.current_display_time = self.app_config_fields.default_time_value;
self.net_state.force_update = true;
if self.app_config_fields.autohide_time {
self.net_state.autohide_timer = Some(Instant::now());
}
}
fn reset_zoom(&mut self) { fn reset_zoom(&mut self) {
match self.current_widget_selected { match self.current_widget_selected {
WidgetPosition::Cpu => { WidgetPosition::Cpu => self.reset_cpu_zoom(),
self.cpu_state.display_time = self.app_config_fields.default_time_value; WidgetPosition::Mem => self.reset_mem_zoom(),
self.cpu_state.force_update = true; WidgetPosition::Network => self.reset_net_zoom(),
if self.app_config_fields.autohide_time {
self.cpu_state.display_time_instant = Some(Instant::now());
}
}
WidgetPosition::Mem => {
self.mem_state.display_time = self.app_config_fields.default_time_value;
self.mem_state.force_update = true;
if self.app_config_fields.autohide_time {
self.mem_state.display_time_instant = Some(Instant::now());
}
}
WidgetPosition::Network => {
self.net_state.display_time = self.app_config_fields.default_time_value;
self.net_state.force_update = true;
if self.app_config_fields.autohide_time {
self.net_state.display_time_instant = Some(Instant::now());
}
}
_ => {} _ => {}
} }
} }

View File

@ -80,6 +80,20 @@ impl Default for DataCollection {
} }
impl DataCollection { impl DataCollection {
pub fn reset(&mut self) {
self.timed_data_vec = Vec::default();
self.network_harvest = network::NetworkHarvest::default();
self.memory_harvest = mem::MemHarvest::default();
self.swap_harvest = mem::MemHarvest::default();
self.cpu_harvest = cpu::CPUHarvest::default();
self.process_harvest = Vec::default();
self.disk_harvest = Vec::default();
self.io_harvest = disks::IOHarvest::default();
self.io_labels = Vec::default();
self.io_prev = Vec::default();
self.temp_harvest = Vec::default();
}
pub fn set_frozen_time(&mut self) { pub fn set_frozen_time(&mut self) {
self.frozen_instant = Some(self.current_instant); self.frozen_instant = Some(self.current_instant);
} }

View File

@ -4,6 +4,8 @@ use std::{collections::HashMap, time::Instant};
use sysinfo::{System, SystemExt}; use sysinfo::{System, SystemExt};
use futures::join;
pub mod cpu; pub mod cpu;
pub mod disks; pub mod disks;
pub mod mem; pub mod mem;

View File

@ -232,9 +232,6 @@ pub fn get_sorted_processes_list(
} }
*prev_pid_stats = new_pid_stats; *prev_pid_stats = new_pid_stats;
} else {
error!("Unable to properly parse CPU data in Linux.");
error!("Result: {:?}", cpu_calc.err());
} }
} else { } else {
let process_hashmap = sys.get_processes(); let process_hashmap = sys.get_processes();

View File

@ -129,9 +129,7 @@ impl Painter {
} }
} }
// TODO: [REFACTOR] We should clean this up tbh
// TODO: [FEATURE] Auto-resizing dialog sizes. // TODO: [FEATURE] Auto-resizing dialog sizes.
#[allow(clippy::cognitive_complexity)]
pub fn draw_data<B: Backend>( pub fn draw_data<B: Backend>(
&mut self, terminal: &mut Terminal<B>, app_state: &mut app::App, &mut self, terminal: &mut Terminal<B>, app_state: &mut app::App,
) -> error::Result<()> { ) -> error::Result<()> {
@ -139,9 +137,6 @@ impl Painter {
let current_height = terminal_size.height; let current_height = terminal_size.height;
let current_width = terminal_size.width; let current_width = terminal_size.width;
// TODO: [OPT] we might be able to add an argument s.t. if there is
// no resize AND it's not a data update (or process refresh/search/etc.)
// then just... don't draw again!
if self.height == 0 && self.width == 0 { if self.height == 0 && self.width == 0 {
self.height = current_height; self.height = current_height;
self.width = current_width; self.width = current_width;
@ -336,7 +331,6 @@ impl Painter {
); );
} }
} else { } else {
// TODO: [TUI] Change this back to a more even 33/33/34 when TUI releases
let vertical_chunks = Layout::default() let vertical_chunks = Layout::default()
.direction(Direction::Vertical) .direction(Direction::Vertical)
.margin(1) .margin(1)

View File

@ -1,3 +1,4 @@
use lazy_static::lazy_static;
use std::collections::HashMap; use std::collections::HashMap;
use tui::style::{Color, Style}; use tui::style::{Color, Style};

View File

@ -1,3 +1,4 @@
use lazy_static::lazy_static;
use std::borrow::Cow; use std::borrow::Cow;
use std::cmp::max; use std::cmp::max;
@ -45,31 +46,31 @@ impl CpuGraphWidget for Painter {
let cpu_data: &[ConvertedCpuData] = &app_state.canvas_data.cpu_data; let cpu_data: &[ConvertedCpuData] = &app_state.canvas_data.cpu_data;
let display_time_labels = [ let display_time_labels = [
format!("{}s", app_state.cpu_state.display_time / 1000), format!("{}s", app_state.cpu_state.current_display_time / 1000),
"0s".to_string(), "0s".to_string(),
]; ];
let x_axis = if app_state.app_config_fields.hide_time let x_axis = if app_state.app_config_fields.hide_time
|| (app_state.app_config_fields.autohide_time || (app_state.app_config_fields.autohide_time
&& app_state.cpu_state.display_time_instant.is_none()) && app_state.cpu_state.autohide_timer.is_none())
{ {
Axis::default().bounds([0.0, app_state.cpu_state.display_time as f64]) Axis::default().bounds([0.0, app_state.cpu_state.current_display_time as f64])
} else if let Some(time) = app_state.cpu_state.display_time_instant { } else if let Some(time) = app_state.cpu_state.autohide_timer {
if std::time::Instant::now().duration_since(time).as_millis() if std::time::Instant::now().duration_since(time).as_millis()
< AUTOHIDE_TIMEOUT_MILLISECONDS as u128 < AUTOHIDE_TIMEOUT_MILLISECONDS as u128
{ {
Axis::default() Axis::default()
.bounds([0.0, app_state.cpu_state.display_time as f64]) .bounds([0.0, app_state.cpu_state.current_display_time as f64])
.style(self.colours.graph_style) .style(self.colours.graph_style)
.labels_style(self.colours.graph_style) .labels_style(self.colours.graph_style)
.labels(&display_time_labels) .labels(&display_time_labels)
} else { } else {
app_state.cpu_state.display_time_instant = None; app_state.cpu_state.autohide_timer = None;
Axis::default().bounds([0.0, app_state.cpu_state.display_time as f64]) Axis::default().bounds([0.0, app_state.cpu_state.current_display_time as f64])
} }
} else { } else {
Axis::default() Axis::default()
.bounds([0.0, app_state.cpu_state.display_time as f64]) .bounds([0.0, app_state.cpu_state.current_display_time as f64])
.style(self.colours.graph_style) .style(self.colours.graph_style)
.labels_style(self.colours.graph_style) .labels_style(self.colours.graph_style)
.labels(&display_time_labels) .labels(&display_time_labels)

View File

@ -1,5 +1,5 @@
use lazy_static::lazy_static;
use std::cmp::max; use std::cmp::max;
use tui::{ use tui::{
backend::Backend, backend::Backend,
layout::{Constraint, Direction, Layout, Rect}, layout::{Constraint, Direction, Layout, Rect},

View File

@ -27,30 +27,30 @@ impl MemGraphWidget for Painter {
let swap_data: &[(f64, f64)] = &app_state.canvas_data.swap_data; let swap_data: &[(f64, f64)] = &app_state.canvas_data.swap_data;
let display_time_labels = [ let display_time_labels = [
format!("{}s", app_state.mem_state.display_time / 1000), format!("{}s", app_state.mem_state.current_display_time / 1000),
"0s".to_string(), "0s".to_string(),
]; ];
let x_axis = if app_state.app_config_fields.hide_time let x_axis = if app_state.app_config_fields.hide_time
|| (app_state.app_config_fields.autohide_time || (app_state.app_config_fields.autohide_time
&& app_state.mem_state.display_time_instant.is_none()) && app_state.mem_state.autohide_timer.is_none())
{ {
Axis::default().bounds([0.0, app_state.mem_state.display_time as f64]) Axis::default().bounds([0.0, app_state.mem_state.current_display_time as f64])
} else if let Some(time) = app_state.mem_state.display_time_instant { } else if let Some(time) = app_state.mem_state.autohide_timer {
if std::time::Instant::now().duration_since(time).as_millis() if std::time::Instant::now().duration_since(time).as_millis()
< AUTOHIDE_TIMEOUT_MILLISECONDS as u128 < AUTOHIDE_TIMEOUT_MILLISECONDS as u128
{ {
Axis::default() Axis::default()
.bounds([0.0, app_state.mem_state.display_time as f64]) .bounds([0.0, app_state.mem_state.current_display_time as f64])
.style(self.colours.graph_style) .style(self.colours.graph_style)
.labels_style(self.colours.graph_style) .labels_style(self.colours.graph_style)
.labels(&display_time_labels) .labels(&display_time_labels)
} else { } else {
app_state.mem_state.display_time_instant = None; app_state.mem_state.autohide_timer = None;
Axis::default().bounds([0.0, app_state.mem_state.display_time as f64]) Axis::default().bounds([0.0, app_state.mem_state.current_display_time as f64])
} }
} else { } else {
Axis::default() Axis::default()
.bounds([0.0, app_state.mem_state.display_time as f64]) .bounds([0.0, app_state.mem_state.current_display_time as f64])
.style(self.colours.graph_style) .style(self.colours.graph_style)
.labels_style(self.colours.graph_style) .labels_style(self.colours.graph_style)
.labels(&display_time_labels) .labels(&display_time_labels)

View File

@ -1,3 +1,4 @@
use lazy_static::lazy_static;
use std::cmp::max; use std::cmp::max;
use crate::{ use crate::{
@ -40,30 +41,30 @@ impl NetworkGraphWidget for Painter {
let network_data_tx: &[(f64, f64)] = &app_state.canvas_data.network_data_tx; let network_data_tx: &[(f64, f64)] = &app_state.canvas_data.network_data_tx;
let display_time_labels = [ let display_time_labels = [
format!("{}s", app_state.net_state.display_time / 1000), format!("{}s", app_state.net_state.current_display_time / 1000),
"0s".to_string(), "0s".to_string(),
]; ];
let x_axis = if app_state.app_config_fields.hide_time let x_axis = if app_state.app_config_fields.hide_time
|| (app_state.app_config_fields.autohide_time || (app_state.app_config_fields.autohide_time
&& app_state.net_state.display_time_instant.is_none()) && app_state.net_state.autohide_timer.is_none())
{ {
Axis::default().bounds([0.0, app_state.net_state.display_time as f64]) Axis::default().bounds([0.0, app_state.net_state.current_display_time as f64])
} else if let Some(time) = app_state.net_state.display_time_instant { } else if let Some(time) = app_state.net_state.autohide_timer {
if std::time::Instant::now().duration_since(time).as_millis() if std::time::Instant::now().duration_since(time).as_millis()
< AUTOHIDE_TIMEOUT_MILLISECONDS as u128 < AUTOHIDE_TIMEOUT_MILLISECONDS as u128
{ {
Axis::default() Axis::default()
.bounds([0.0, app_state.net_state.display_time as f64]) .bounds([0.0, app_state.net_state.current_display_time as f64])
.style(self.colours.graph_style) .style(self.colours.graph_style)
.labels_style(self.colours.graph_style) .labels_style(self.colours.graph_style)
.labels(&display_time_labels) .labels(&display_time_labels)
} else { } else {
app_state.net_state.display_time_instant = None; app_state.net_state.autohide_timer = None;
Axis::default().bounds([0.0, app_state.net_state.display_time as f64]) Axis::default().bounds([0.0, app_state.net_state.current_display_time as f64])
} }
} else { } else {
Axis::default() Axis::default()
.bounds([0.0, app_state.net_state.display_time as f64]) .bounds([0.0, app_state.net_state.current_display_time as f64])
.style(self.colours.graph_style) .style(self.colours.graph_style)
.labels_style(self.colours.graph_style) .labels_style(self.colours.graph_style)
.labels(&display_time_labels) .labels(&display_time_labels)

View File

@ -1,3 +1,4 @@
use lazy_static::lazy_static;
use std::cmp::max; use std::cmp::max;
use tui::{ use tui::{

View File

@ -1,3 +1,5 @@
use lazy_static::lazy_static;
// How long to store data. // How long to store data.
pub const STALE_MAX_MILLISECONDS: u64 = 600 * 1000; // Keep 10 minutes of data. pub const STALE_MAX_MILLISECONDS: u64 = 600 * 1000; // Keep 10 minutes of data.

View File

@ -272,7 +272,7 @@ pub fn get_rx_tx_data_points(
current_data.current_instant current_data.current_instant
}; };
// TODO: [REFACTOR] Can we use combine on this, CPU, and MEM? // TODO: [REFACTOR] Can we use collect on this, CPU, and MEM?
for (time, data) in &current_data.timed_data_vec { for (time, data) in &current_data.timed_data_vec {
let time_from_start: f64 = let time_from_start: f64 =
(display_time as f64 - current_time.duration_since(*time).as_millis() as f64).floor(); (display_time as f64 - current_time.duration_since(*time).as_millis() as f64).floor();

View File

@ -1,11 +1,5 @@
#![warn(rust_2018_idioms)] #![warn(rust_2018_idioms)]
#[macro_use]
extern crate clap;
#[macro_use]
extern crate futures;
#[macro_use]
extern crate lazy_static;
#[macro_use] #[macro_use]
extern crate log; extern crate log;
@ -18,6 +12,8 @@ use std::{
time::{Duration, Instant}, time::{Duration, Instant},
}; };
use clap::*;
use crossterm::{ use crossterm::{
event::{ event::{
poll, read, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEvent, poll, read, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEvent,
@ -109,42 +105,14 @@ fn main() -> error::Result<()> {
let config: Config = create_config(matches.value_of("CONFIG_LOCATION"))?; let config: Config = create_config(matches.value_of("CONFIG_LOCATION"))?;
let update_rate_in_milliseconds: u64 =
get_update_rate_in_milliseconds(&matches.value_of("RATE_MILLIS"), &config)?;
// Set other settings
let temperature_type = get_temperature_option(&matches, &config)?;
let show_average_cpu = get_avg_cpu_option(&matches, &config);
let use_dot = get_use_dot_option(&matches, &config);
let left_legend = get_use_left_legend_option(&matches, &config);
let use_current_cpu_total = get_use_current_cpu_total_option(&matches, &config);
let current_widget_selected = get_default_widget(&matches, &config);
let show_disabled_data = get_show_disabled_data_option(&matches, &config);
let use_basic_mode = get_use_basic_mode_option(&matches, &config);
let default_time_value = get_default_time_value_option(&matches, &config)?;
let time_interval = get_time_interval_option(&matches, &config)?;
// Create "app" struct, which will control most of the program and store settings/state // Create "app" struct, which will control most of the program and store settings/state
let mut app = App::new( let mut app = build_app(&matches, &config)?;
show_average_cpu,
temperature_type,
update_rate_in_milliseconds,
use_dot,
left_legend,
use_current_cpu_total,
current_widget_selected,
show_disabled_data,
use_basic_mode,
default_time_value,
time_interval,
);
// TODO: [REFACTOR] Change this
enable_app_grouping(&matches, &config, &mut app); enable_app_grouping(&matches, &config, &mut app);
enable_app_case_sensitive(&matches, &config, &mut app); enable_app_case_sensitive(&matches, &config, &mut app);
enable_app_match_whole_word(&matches, &config, &mut app); enable_app_match_whole_word(&matches, &config, &mut app);
enable_app_use_regex(&matches, &config, &mut app); enable_app_use_regex(&matches, &config, &mut app);
enable_hide_time(&matches, &config, &mut app);
enable_autohide_time(&matches, &config, &mut app);
// Set up up tui and crossterm // Set up up tui and crossterm
let mut stdout_val = stdout(); let mut stdout_val = stdout();
@ -166,7 +134,7 @@ fn main() -> error::Result<()> {
let tx = tx.clone(); let tx = tx.clone();
thread::spawn(move || loop { thread::spawn(move || loop {
thread::sleep(Duration::from_millis( thread::sleep(Duration::from_millis(
constants::STALE_MAX_MILLISECONDS as u64 + 5000, constants::STALE_MAX_MILLISECONDS + 5000,
)); ));
tx.send(BottomEvent::Clean).unwrap(); tx.send(BottomEvent::Clean).unwrap();
}); });
@ -176,8 +144,8 @@ fn main() -> error::Result<()> {
create_event_thread( create_event_thread(
tx, tx,
rrx, rrx,
use_current_cpu_total, app.app_config_fields.use_current_cpu_total,
update_rate_in_milliseconds as u64, app.app_config_fields.update_rate_in_milliseconds,
app.app_config_fields.temperature_type.clone(), app.app_config_fields.temperature_type.clone(),
app.app_config_fields.show_average_cpu, app.app_config_fields.show_average_cpu,
); );
@ -213,7 +181,7 @@ fn main() -> error::Result<()> {
// Network // Network
let network_data = convert_network_data_points( let network_data = convert_network_data_points(
&app.data_collection, &app.data_collection,
app.net_state.display_time, app.net_state.current_display_time,
false, false,
); );
app.canvas_data.network_data_rx = network_data.rx; app.canvas_data.network_data_rx = network_data.rx;
@ -231,12 +199,12 @@ fn main() -> error::Result<()> {
// Memory // Memory
app.canvas_data.mem_data = convert_mem_data_points( app.canvas_data.mem_data = convert_mem_data_points(
&app.data_collection, &app.data_collection,
app.mem_state.display_time, app.mem_state.current_display_time,
false, false,
); );
app.canvas_data.swap_data = convert_swap_data_points( app.canvas_data.swap_data = convert_swap_data_points(
&app.data_collection, &app.data_collection,
app.mem_state.display_time, app.mem_state.current_display_time,
false, false,
); );
let memory_and_swap_labels = convert_mem_labels(&app.data_collection); let memory_and_swap_labels = convert_mem_labels(&app.data_collection);
@ -254,7 +222,7 @@ fn main() -> error::Result<()> {
// CPU // CPU
app.canvas_data.cpu_data = convert_cpu_data_points( app.canvas_data.cpu_data = convert_cpu_data_points(
&app.data_collection, &app.data_collection,
app.cpu_state.display_time, app.cpu_state.current_display_time,
false, false,
); );
@ -590,7 +558,7 @@ fn handle_force_redraws(app: &mut App) {
if app.cpu_state.force_update { if app.cpu_state.force_update {
app.canvas_data.cpu_data = convert_cpu_data_points( app.canvas_data.cpu_data = convert_cpu_data_points(
&app.data_collection, &app.data_collection,
app.cpu_state.display_time, app.cpu_state.current_display_time,
app.is_frozen, app.is_frozen,
); );
app.cpu_state.force_update = false; app.cpu_state.force_update = false;
@ -599,12 +567,12 @@ fn handle_force_redraws(app: &mut App) {
if app.mem_state.force_update { if app.mem_state.force_update {
app.canvas_data.mem_data = convert_mem_data_points( app.canvas_data.mem_data = convert_mem_data_points(
&app.data_collection, &app.data_collection,
app.mem_state.display_time, app.mem_state.current_display_time,
app.is_frozen, app.is_frozen,
); );
app.canvas_data.swap_data = convert_swap_data_points( app.canvas_data.swap_data = convert_swap_data_points(
&app.data_collection, &app.data_collection,
app.mem_state.display_time, app.mem_state.current_display_time,
app.is_frozen, app.is_frozen,
); );
app.mem_state.force_update = false; app.mem_state.force_update = false;
@ -613,7 +581,7 @@ fn handle_force_redraws(app: &mut App) {
if app.net_state.force_update { if app.net_state.force_update {
let (rx, tx) = get_rx_tx_data_points( let (rx, tx) = get_rx_tx_data_points(
&app.data_collection, &app.data_collection,
app.net_state.display_time, app.net_state.current_display_time,
app.is_frozen, app.is_frozen,
); );
app.canvas_data.network_data_rx = rx; app.canvas_data.network_data_rx = rx;

View File

@ -1,11 +1,17 @@
use serde::Deserialize; use serde::Deserialize;
use std::time::Instant;
use crate::{ use crate::{
app::{data_harvester, App, WidgetPosition}, app::{data_harvester, App, AppConfigFields, CpuState, MemState, NetState, WidgetPosition},
constants::*, constants::*,
utils::error::{self, BottomError}, utils::error::{self, BottomError},
}; };
// use layout_manager::*;
// mod layout_manager;
#[derive(Default, Deserialize)] #[derive(Default, Deserialize)]
pub struct Config { pub struct Config {
pub flags: Option<ConfigFlags>, pub flags: Option<ConfigFlags>,
@ -54,10 +60,64 @@ pub struct ConfigColours {
pub graph_color: Option<String>, pub graph_color: Option<String>,
} }
pub fn get_update_rate_in_milliseconds( pub fn build_app(matches: &clap::ArgMatches<'static>, config: &Config) -> error::Result<App> {
update_rate: &Option<&str>, config: &Config, let autohide_time = get_autohide_time(&matches, &config);
let default_time_value = get_default_time_value(&matches, &config)?;
let default_widget = get_default_widget(&matches, &config);
let use_basic_mode = get_use_basic_mode(&matches, &config);
let current_widget_selected = if use_basic_mode {
match default_widget {
WidgetPosition::Cpu => WidgetPosition::BasicCpu,
WidgetPosition::Network => WidgetPosition::BasicNet,
WidgetPosition::Mem => WidgetPosition::BasicMem,
_ => default_widget,
}
} else {
default_widget
};
let previous_basic_table_selected = if default_widget.is_widget_table() {
default_widget
} else {
WidgetPosition::Process
};
let app_config_fields = AppConfigFields {
update_rate_in_milliseconds: get_update_rate_in_milliseconds(matches, config)?,
temperature_type: get_temperature(matches, config)?,
show_average_cpu: get_avg_cpu(matches, config),
use_dot: get_use_dot(matches, config),
left_legend: get_use_left_legend(matches, config),
use_current_cpu_total: get_use_current_cpu_total(matches, config),
show_disabled_data: get_show_disabled_data(matches, config),
use_basic_mode,
default_time_value,
time_interval: get_time_interval(matches, config)?,
hide_time: get_hide_time(matches, config),
autohide_time,
};
let time_now = if autohide_time {
Some(Instant::now())
} else {
None
};
Ok(App::builder()
.app_config_fields(app_config_fields)
.current_widget_selected(current_widget_selected)
.previous_basic_table_selected(previous_basic_table_selected)
.cpu_state(CpuState::init(default_time_value, time_now))
.mem_state(MemState::init(default_time_value, time_now))
.net_state(NetState::init(default_time_value, time_now))
.build())
}
fn get_update_rate_in_milliseconds(
matches: &clap::ArgMatches<'static>, config: &Config,
) -> error::Result<u64> { ) -> error::Result<u64> {
let update_rate_in_milliseconds = if let Some(update_rate) = update_rate { let update_rate_in_milliseconds = if let Some(update_rate) = matches.value_of("RATE_MILLIS") {
update_rate.parse::<u128>()? update_rate.parse::<u128>()?
} else if let Some(flags) = &config.flags { } else if let Some(flags) = &config.flags {
if let Some(rate) = flags.rate { if let Some(rate) = flags.rate {
@ -82,7 +142,7 @@ pub fn get_update_rate_in_milliseconds(
Ok(update_rate_in_milliseconds as u64) Ok(update_rate_in_milliseconds as u64)
} }
pub fn get_temperature_option( fn get_temperature(
matches: &clap::ArgMatches<'static>, config: &Config, matches: &clap::ArgMatches<'static>, config: &Config,
) -> error::Result<data_harvester::temperature::TemperatureType> { ) -> error::Result<data_harvester::temperature::TemperatureType> {
if matches.is_present("FAHRENHEIT") { if matches.is_present("FAHRENHEIT") {
@ -109,7 +169,7 @@ pub fn get_temperature_option(
Ok(data_harvester::temperature::TemperatureType::Celsius) Ok(data_harvester::temperature::TemperatureType::Celsius)
} }
pub fn get_avg_cpu_option(matches: &clap::ArgMatches<'static>, config: &Config) -> bool { fn get_avg_cpu(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
if matches.is_present("AVG_CPU") { if matches.is_present("AVG_CPU") {
return true; return true;
} else if let Some(flags) = &config.flags { } else if let Some(flags) = &config.flags {
@ -121,7 +181,7 @@ pub fn get_avg_cpu_option(matches: &clap::ArgMatches<'static>, config: &Config)
false false
} }
pub fn get_use_dot_option(matches: &clap::ArgMatches<'static>, config: &Config) -> bool { fn get_use_dot(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
if matches.is_present("DOT_MARKER") { if matches.is_present("DOT_MARKER") {
return true; return true;
} else if let Some(flags) = &config.flags { } else if let Some(flags) = &config.flags {
@ -132,7 +192,7 @@ pub fn get_use_dot_option(matches: &clap::ArgMatches<'static>, config: &Config)
false false
} }
pub fn get_use_left_legend_option(matches: &clap::ArgMatches<'static>, config: &Config) -> bool { fn get_use_left_legend(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
if matches.is_present("LEFT_LEGEND") { if matches.is_present("LEFT_LEGEND") {
return true; return true;
} else if let Some(flags) = &config.flags { } else if let Some(flags) = &config.flags {
@ -144,9 +204,7 @@ pub fn get_use_left_legend_option(matches: &clap::ArgMatches<'static>, config: &
false false
} }
pub fn get_use_current_cpu_total_option( fn get_use_current_cpu_total(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
matches: &clap::ArgMatches<'static>, config: &Config,
) -> bool {
if matches.is_present("USE_CURR_USAGE") { if matches.is_present("USE_CURR_USAGE") {
return true; return true;
} else if let Some(flags) = &config.flags { } else if let Some(flags) = &config.flags {
@ -158,7 +216,7 @@ pub fn get_use_current_cpu_total_option(
false false
} }
pub fn get_show_disabled_data_option(matches: &clap::ArgMatches<'static>, config: &Config) -> bool { fn get_show_disabled_data(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
if matches.is_present("SHOW_DISABLED_DATA") { if matches.is_present("SHOW_DISABLED_DATA") {
return true; return true;
} else if let Some(flags) = &config.flags { } else if let Some(flags) = &config.flags {
@ -170,7 +228,7 @@ pub fn get_show_disabled_data_option(matches: &clap::ArgMatches<'static>, config
false false
} }
pub fn get_use_basic_mode_option(matches: &clap::ArgMatches<'static>, config: &Config) -> bool { fn get_use_basic_mode(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
if matches.is_present("BASIC_MODE") { if matches.is_present("BASIC_MODE") {
return true; return true;
} else if let Some(flags) = &config.flags { } else if let Some(flags) = &config.flags {
@ -182,7 +240,7 @@ pub fn get_use_basic_mode_option(matches: &clap::ArgMatches<'static>, config: &C
false false
} }
pub fn get_default_time_value_option( fn get_default_time_value(
matches: &clap::ArgMatches<'static>, config: &Config, matches: &clap::ArgMatches<'static>, config: &Config,
) -> error::Result<u64> { ) -> error::Result<u64> {
let default_time = if let Some(default_time_value) = matches.value_of("DEFAULT_TIME_VALUE") { let default_time = if let Some(default_time_value) = matches.value_of("DEFAULT_TIME_VALUE") {
@ -202,17 +260,16 @@ pub fn get_default_time_value_option(
"Please set your default value to be at least 30000 milliseconds.".to_string(), "Please set your default value to be at least 30000 milliseconds.".to_string(),
)); ));
} else if default_time as u128 > STALE_MAX_MILLISECONDS as u128 { } else if default_time as u128 > STALE_MAX_MILLISECONDS as u128 {
return Err(BottomError::InvalidArg( return Err(BottomError::InvalidArg(format!(
format!("Please set your default value to be at most {} milliseconds.", STALE_MAX_MILLISECONDS), "Please set your default value to be at most {} milliseconds.",
)); STALE_MAX_MILLISECONDS
)));
} }
Ok(default_time as u64) Ok(default_time as u64)
} }
pub fn get_time_interval_option( fn get_time_interval(matches: &clap::ArgMatches<'static>, config: &Config) -> error::Result<u64> {
matches: &clap::ArgMatches<'static>, config: &Config,
) -> error::Result<u64> {
let time_interval = if let Some(time_interval) = matches.value_of("TIME_DELTA") { let time_interval = if let Some(time_interval) = matches.value_of("TIME_DELTA") {
time_interval.parse::<u128>()? time_interval.parse::<u128>()?
} else if let Some(flags) = &config.flags { } else if let Some(flags) = &config.flags {
@ -230,9 +287,10 @@ pub fn get_time_interval_option(
"Please set your time delta to be at least 1000 milliseconds.".to_string(), "Please set your time delta to be at least 1000 milliseconds.".to_string(),
)); ));
} else if time_interval > STALE_MAX_MILLISECONDS as u128 { } else if time_interval > STALE_MAX_MILLISECONDS as u128 {
return Err(BottomError::InvalidArg( return Err(BottomError::InvalidArg(format!(
format!("Please set your time delta to be at most {} milliseconds.", STALE_MAX_MILLISECONDS), "Please set your time delta to be at most {} milliseconds.",
)); STALE_MAX_MILLISECONDS
)));
} }
Ok(time_interval as u64) Ok(time_interval as u64)
@ -290,39 +348,34 @@ pub fn enable_app_use_regex(matches: &clap::ArgMatches<'static>, config: &Config
} }
} }
pub fn enable_hide_time(matches: &clap::ArgMatches<'static>, config: &Config, app: &mut App) { fn get_hide_time(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
if matches.is_present("HIDE_TIME") { if matches.is_present("HIDE_TIME") {
app.app_config_fields.hide_time = true; return true;
} else if let Some(flags) = &config.flags { } else if let Some(flags) = &config.flags {
if let Some(hide_time) = flags.hide_time { if let Some(hide_time) = flags.hide_time {
if hide_time { if hide_time {
app.app_config_fields.hide_time = true; return true;
} }
} }
} }
false
} }
pub fn enable_autohide_time(matches: &clap::ArgMatches<'static>, config: &Config, app: &mut App) { fn get_autohide_time(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
if matches.is_present("AUTOHIDE_TIME") { if matches.is_present("AUTOHIDE_TIME") {
app.app_config_fields.autohide_time = true; return true;
let time = Some(std::time::Instant::now());
app.cpu_state.display_time_instant = time;
app.mem_state.display_time_instant = time;
app.net_state.display_time_instant = time;
} else if let Some(flags) = &config.flags { } else if let Some(flags) = &config.flags {
if let Some(autohide_time) = flags.autohide_time { if let Some(autohide_time) = flags.autohide_time {
if autohide_time { if autohide_time {
app.app_config_fields.autohide_time = true; return true;
let time = Some(std::time::Instant::now());
app.cpu_state.display_time_instant = time;
app.mem_state.display_time_instant = time;
app.net_state.display_time_instant = time;
} }
} }
} }
false
} }
pub fn get_default_widget(matches: &clap::ArgMatches<'static>, config: &Config) -> WidgetPosition { fn get_default_widget(matches: &clap::ArgMatches<'static>, config: &Config) -> WidgetPosition {
if matches.is_present("CPU_WIDGET") { if matches.is_present("CPU_WIDGET") {
return WidgetPosition::Cpu; return WidgetPosition::Cpu;
} else if matches.is_present("MEM_WIDGET") { } else if matches.is_present("MEM_WIDGET") {

View File

@ -0,0 +1,3 @@
use serde::Deserialize;
use toml::Value;