mirror of
https://github.com/ClementTsang/bottom.git
synced 2025-07-27 15:44:17 +02:00
Refactoring.
This commit is contained in:
parent
ff43799037
commit
eb2622467f
@ -300,7 +300,7 @@ impl App {
|
|||||||
left_legend,
|
left_legend,
|
||||||
use_current_cpu_total,
|
use_current_cpu_total,
|
||||||
show_disabled_data,
|
show_disabled_data,
|
||||||
use_basic_mode
|
use_basic_mode,
|
||||||
},
|
},
|
||||||
is_expanded: false,
|
is_expanded: false,
|
||||||
is_resized: false,
|
is_resized: false,
|
||||||
@ -712,8 +712,7 @@ impl App {
|
|||||||
|
|
||||||
pub fn on_up_key(&mut self) {
|
pub fn on_up_key(&mut self) {
|
||||||
if !self.is_in_dialog() {
|
if !self.is_in_dialog() {
|
||||||
if let WidgetPosition::ProcessSearch = self.current_widget_selected {
|
if let WidgetPosition::ProcessSearch = self.current_widget_selected {} else {
|
||||||
} else {
|
|
||||||
self.decrement_position_count();
|
self.decrement_position_count();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -721,8 +720,7 @@ impl App {
|
|||||||
|
|
||||||
pub fn on_down_key(&mut self) {
|
pub fn on_down_key(&mut self) {
|
||||||
if !self.is_in_dialog() {
|
if !self.is_in_dialog() {
|
||||||
if let WidgetPosition::ProcessSearch = self.current_widget_selected {
|
if let WidgetPosition::ProcessSearch = self.current_widget_selected {} else {
|
||||||
} else {
|
|
||||||
self.increment_position_count();
|
self.increment_position_count();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,15 +37,13 @@ pub async fn get_temperature_data(
|
|||||||
temperature: match temp_type {
|
temperature: match temp_type {
|
||||||
TemperatureType::Celsius => sensor
|
TemperatureType::Celsius => sensor
|
||||||
.current()
|
.current()
|
||||||
.get::<thermodynamic_temperature::degree_celsius>(
|
.get::<thermodynamic_temperature::degree_celsius>(),
|
||||||
),
|
|
||||||
TemperatureType::Kelvin => {
|
TemperatureType::Kelvin => {
|
||||||
sensor.current().get::<thermodynamic_temperature::kelvin>()
|
sensor.current().get::<thermodynamic_temperature::kelvin>()
|
||||||
}
|
}
|
||||||
TemperatureType::Fahrenheit => sensor
|
TemperatureType::Fahrenheit => sensor
|
||||||
.current()
|
.current()
|
||||||
.get::<thermodynamic_temperature::degree_fahrenheit>(
|
.get::<thermodynamic_temperature::degree_fahrenheit>(),
|
||||||
),
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -73,9 +73,12 @@ pub struct DisplayableData {
|
|||||||
pub network_data_tx: Vec<(f64, f64)>,
|
pub network_data_tx: Vec<(f64, f64)>,
|
||||||
pub disk_data: Vec<Vec<String>>,
|
pub disk_data: Vec<Vec<String>>,
|
||||||
pub temp_sensor_data: Vec<Vec<String>>,
|
pub temp_sensor_data: Vec<Vec<String>>,
|
||||||
pub process_data: HashMap<u32, ProcessHarvest>, // Not the final value
|
pub process_data: HashMap<u32, ProcessHarvest>,
|
||||||
pub grouped_process_data: Vec<ConvertedProcessData>, // Not the final value
|
// Not the final value
|
||||||
pub finalized_process_data: Vec<ConvertedProcessData>, // What's actually displayed
|
pub grouped_process_data: Vec<ConvertedProcessData>,
|
||||||
|
// Not the final value
|
||||||
|
pub finalized_process_data: Vec<ConvertedProcessData>,
|
||||||
|
// What's actually displayed
|
||||||
pub mem_label: String,
|
pub mem_label: String,
|
||||||
pub swap_label: String,
|
pub swap_label: String,
|
||||||
pub mem_data: Vec<(f64, f64)>,
|
pub mem_data: Vec<(f64, f64)>,
|
||||||
|
@ -4,7 +4,8 @@ use tui::style::{Color, Style};
|
|||||||
|
|
||||||
use crate::utils::{error, gen_util::*};
|
use crate::utils::{error, gen_util::*};
|
||||||
|
|
||||||
const GOLDEN_RATIO: f32 = 0.618_034; // Approx, good enough for use (also Clippy gets mad if it's too long)
|
const GOLDEN_RATIO: f32 = 0.618_034;
|
||||||
|
// Approx, good enough for use (also Clippy gets mad if it's too long)
|
||||||
pub const STANDARD_FIRST_COLOUR: Color = Color::LightMagenta;
|
pub const STANDARD_FIRST_COLOUR: Color = Color::LightMagenta;
|
||||||
pub const STANDARD_SECOND_COLOUR: Color = Color::LightYellow;
|
pub const STANDARD_SECOND_COLOUR: Color = Color::LightYellow;
|
||||||
pub const STANDARD_THIRD_COLOUR: Color = Color::LightCyan;
|
pub const STANDARD_THIRD_COLOUR: Color = Color::LightCyan;
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
pub const STALE_MAX_MILLISECONDS: u128 = 60 * 1000; // How long to store data.
|
pub const STALE_MAX_MILLISECONDS: u128 = 60 * 1000;
|
||||||
|
// How long to store data.
|
||||||
pub const TIME_STARTS_FROM: u64 = 60 * 1000;
|
pub const TIME_STARTS_FROM: u64 = 60 * 1000;
|
||||||
pub const TICK_RATE_IN_MILLISECONDS: u64 = 200; // How fast the screen refreshes
|
pub const TICK_RATE_IN_MILLISECONDS: u64 = 200;
|
||||||
|
// How fast the screen refreshes
|
||||||
pub const DEFAULT_REFRESH_RATE_IN_MILLISECONDS: u128 = 1000;
|
pub const DEFAULT_REFRESH_RATE_IN_MILLISECONDS: u128 = 1000;
|
||||||
pub const MAX_KEY_TIMEOUT_IN_MILLISECONDS: u128 = 1000;
|
pub const MAX_KEY_TIMEOUT_IN_MILLISECONDS: u128 = 1000;
|
||||||
pub const NUM_COLOURS: i32 = 256;
|
pub const NUM_COLOURS: i32 = 256;
|
||||||
|
284
src/main.rs
284
src/main.rs
@ -20,35 +20,39 @@ use std::{
|
|||||||
|
|
||||||
use crossterm::{
|
use crossterm::{
|
||||||
event::{
|
event::{
|
||||||
poll, read, DisableMouseCapture, EnableMouseCapture, Event as CEvent, KeyCode, KeyEvent,
|
DisableMouseCapture, EnableMouseCapture, Event as CEvent, KeyCode, KeyEvent, KeyModifiers, MouseEvent,
|
||||||
KeyModifiers, MouseEvent,
|
poll, read,
|
||||||
},
|
},
|
||||||
execute,
|
execute,
|
||||||
style::Print,
|
style::Print,
|
||||||
terminal::LeaveAlternateScreen,
|
|
||||||
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen},
|
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen},
|
||||||
|
terminal::LeaveAlternateScreen,
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
|
||||||
use tui::{backend::CrosstermBackend, Terminal};
|
use tui::{backend::CrosstermBackend, Terminal};
|
||||||
|
|
||||||
use app::{
|
use app::{
|
||||||
data_harvester::{self, processes::ProcessSorting},
|
|
||||||
App,
|
App,
|
||||||
|
data_harvester::{self, processes::ProcessSorting},
|
||||||
};
|
};
|
||||||
use constants::*;
|
use constants::*;
|
||||||
use data_conversion::*;
|
use data_conversion::*;
|
||||||
use utils::error::{self, BottomError};
|
use options::*;
|
||||||
|
use utils::error::{self};
|
||||||
|
|
||||||
pub mod app;
|
pub mod app;
|
||||||
|
|
||||||
mod utils {
|
mod utils {
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod gen_util;
|
pub mod gen_util;
|
||||||
pub mod logging;
|
pub mod logging;
|
||||||
}
|
}
|
||||||
|
|
||||||
mod canvas;
|
mod canvas;
|
||||||
mod constants;
|
mod constants;
|
||||||
mod data_conversion;
|
mod data_conversion;
|
||||||
|
|
||||||
|
pub mod options;
|
||||||
|
|
||||||
enum Event<I, J> {
|
enum Event<I, J> {
|
||||||
KeyInput(I),
|
KeyInput(I),
|
||||||
MouseInput(J),
|
MouseInput(J),
|
||||||
@ -60,50 +64,6 @@ enum ResetEvent {
|
|||||||
Reset,
|
Reset,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Deserialize)]
|
|
||||||
struct Config {
|
|
||||||
flags: Option<ConfigFlags>,
|
|
||||||
colors: Option<ConfigColours>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Deserialize)]
|
|
||||||
struct ConfigFlags {
|
|
||||||
avg_cpu: Option<bool>,
|
|
||||||
dot_marker: Option<bool>,
|
|
||||||
temperature_type: Option<String>,
|
|
||||||
rate: Option<u64>,
|
|
||||||
left_legend: Option<bool>,
|
|
||||||
current_usage: Option<bool>,
|
|
||||||
group_processes: Option<bool>,
|
|
||||||
case_sensitive: Option<bool>,
|
|
||||||
whole_word: Option<bool>,
|
|
||||||
regex: Option<bool>,
|
|
||||||
default_widget: Option<String>,
|
|
||||||
show_disabled_data: Option<bool>,
|
|
||||||
basic_mode: Option<bool>,
|
|
||||||
//disabled_cpu_cores: Option<Vec<u64>>, // TODO: [FEATURE] Enable disabling cores in config/flags
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Deserialize)]
|
|
||||||
struct ConfigColours {
|
|
||||||
table_header_color: Option<String>,
|
|
||||||
avg_cpu_color: Option<String>,
|
|
||||||
cpu_core_colors: Option<Vec<String>>,
|
|
||||||
ram_color: Option<String>,
|
|
||||||
swap_color: Option<String>,
|
|
||||||
rx_color: Option<String>,
|
|
||||||
tx_color: Option<String>,
|
|
||||||
rx_total_color: Option<String>,
|
|
||||||
tx_total_color: Option<String>,
|
|
||||||
border_color: Option<String>,
|
|
||||||
highlighted_border_color: Option<String>,
|
|
||||||
text_color: Option<String>,
|
|
||||||
selected_text_color: Option<String>,
|
|
||||||
selected_bg_color: Option<String>,
|
|
||||||
widget_title_color: Option<String>,
|
|
||||||
graph_color: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_matches() -> clap::ArgMatches<'static> {
|
fn get_matches() -> clap::ArgMatches<'static> {
|
||||||
clap_app!(app =>
|
clap_app!(app =>
|
||||||
(name: crate_name!())
|
(name: crate_name!())
|
||||||
@ -457,230 +417,6 @@ fn create_config(flag_config_location: Option<&str>) -> error::Result<Config> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_update_rate_in_milliseconds(
|
|
||||||
update_rate: &Option<&str>, config: &Config,
|
|
||||||
) -> error::Result<u128> {
|
|
||||||
let update_rate_in_milliseconds = if let Some(update_rate) = update_rate {
|
|
||||||
update_rate.parse::<u128>()?
|
|
||||||
} else if let Some(flags) = &config.flags {
|
|
||||||
if let Some(rate) = flags.rate {
|
|
||||||
rate as u128
|
|
||||||
} else {
|
|
||||||
constants::DEFAULT_REFRESH_RATE_IN_MILLISECONDS
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
constants::DEFAULT_REFRESH_RATE_IN_MILLISECONDS
|
|
||||||
};
|
|
||||||
|
|
||||||
if update_rate_in_milliseconds < 250 {
|
|
||||||
return Err(BottomError::InvalidArg(
|
|
||||||
"Please set your update rate to be greater than 250 milliseconds.".to_string(),
|
|
||||||
));
|
|
||||||
} else if update_rate_in_milliseconds > u128::from(std::u64::MAX) {
|
|
||||||
return Err(BottomError::InvalidArg(
|
|
||||||
"Please set your update rate to be less than unsigned INT_MAX.".to_string(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(update_rate_in_milliseconds)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_temperature_option(
|
|
||||||
matches: &clap::ArgMatches<'static>, config: &Config,
|
|
||||||
) -> error::Result<data_harvester::temperature::TemperatureType> {
|
|
||||||
if matches.is_present("FAHRENHEIT") {
|
|
||||||
return Ok(data_harvester::temperature::TemperatureType::Fahrenheit);
|
|
||||||
} else if matches.is_present("KELVIN") {
|
|
||||||
return Ok(data_harvester::temperature::TemperatureType::Kelvin);
|
|
||||||
} else if matches.is_present("CELSIUS") {
|
|
||||||
return Ok(data_harvester::temperature::TemperatureType::Celsius);
|
|
||||||
} else if let Some(flags) = &config.flags {
|
|
||||||
if let Some(temp_type) = &flags.temperature_type {
|
|
||||||
// Give lowest priority to config.
|
|
||||||
return match temp_type.as_str() {
|
|
||||||
"fahrenheit" | "f" => {
|
|
||||||
Ok(data_harvester::temperature::TemperatureType::Fahrenheit)
|
|
||||||
}
|
|
||||||
"kelvin" | "k" => {
|
|
||||||
Ok(data_harvester::temperature::TemperatureType::Kelvin)
|
|
||||||
}
|
|
||||||
"celsius" | "c" => {
|
|
||||||
Ok(data_harvester::temperature::TemperatureType::Celsius)
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
Err(BottomError::ConfigError(
|
|
||||||
"Invalid temperature type. Please have the value be of the form <kelvin|k|celsius|c|fahrenheit|f>".to_string()
|
|
||||||
))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(data_harvester::temperature::TemperatureType::Celsius)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_avg_cpu_option(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
|
|
||||||
if matches.is_present("AVG_CPU") {
|
|
||||||
return true;
|
|
||||||
} else if let Some(flags) = &config.flags {
|
|
||||||
if let Some(avg_cpu) = flags.avg_cpu {
|
|
||||||
return avg_cpu;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_use_dot_option(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
|
|
||||||
if matches.is_present("DOT_MARKER") {
|
|
||||||
return true;
|
|
||||||
} else if let Some(flags) = &config.flags {
|
|
||||||
if let Some(dot_marker) = flags.dot_marker {
|
|
||||||
return dot_marker;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_use_left_legend_option(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
|
|
||||||
if matches.is_present("LEFT_LEGEND") {
|
|
||||||
return true;
|
|
||||||
} else if let Some(flags) = &config.flags {
|
|
||||||
if let Some(left_legend) = flags.left_legend {
|
|
||||||
return left_legend;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_use_current_cpu_total_option(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
|
|
||||||
if matches.is_present("USE_CURR_USAGE") {
|
|
||||||
return true;
|
|
||||||
} else if let Some(flags) = &config.flags {
|
|
||||||
if let Some(current_usage) = flags.current_usage {
|
|
||||||
return current_usage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_show_disabled_data_option(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
|
|
||||||
if matches.is_present("SHOW_DISABLED_DATA") {
|
|
||||||
return true;
|
|
||||||
} else if let Some(flags) = &config.flags {
|
|
||||||
if let Some(show_disabled_data) = flags.show_disabled_data {
|
|
||||||
return show_disabled_data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_use_basic_mode_option(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
|
|
||||||
if matches.is_present("BASIC_MODE") {
|
|
||||||
return true;
|
|
||||||
} else if let Some(flags) = &config.flags {
|
|
||||||
if let Some(basic_mode) = flags.basic_mode {
|
|
||||||
return basic_mode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn enable_app_grouping(matches: &clap::ArgMatches<'static>, config: &Config, app: &mut App) {
|
|
||||||
if matches.is_present("GROUP_PROCESSES") {
|
|
||||||
app.toggle_grouping();
|
|
||||||
} else if let Some(flags) = &config.flags {
|
|
||||||
if let Some(grouping) = flags.group_processes {
|
|
||||||
if grouping {
|
|
||||||
app.toggle_grouping();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn enable_app_case_sensitive(matches: &clap::ArgMatches<'static>, config: &Config, app: &mut App) {
|
|
||||||
if matches.is_present("CASE_SENSITIVE") {
|
|
||||||
app.process_search_state.search_toggle_ignore_case();
|
|
||||||
} else if let Some(flags) = &config.flags {
|
|
||||||
if let Some(case_sensitive) = flags.case_sensitive {
|
|
||||||
if case_sensitive {
|
|
||||||
app.process_search_state.search_toggle_ignore_case();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn enable_app_match_whole_word(
|
|
||||||
matches: &clap::ArgMatches<'static>, config: &Config, app: &mut App,
|
|
||||||
) {
|
|
||||||
if matches.is_present("WHOLE_WORD") {
|
|
||||||
app.process_search_state.search_toggle_whole_word();
|
|
||||||
} else if let Some(flags) = &config.flags {
|
|
||||||
if let Some(whole_word) = flags.whole_word {
|
|
||||||
if whole_word {
|
|
||||||
app.process_search_state.search_toggle_whole_word();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn enable_app_use_regex(matches: &clap::ArgMatches<'static>, config: &Config, app: &mut App) {
|
|
||||||
if matches.is_present("REGEX_DEFAULT") {
|
|
||||||
app.process_search_state.search_toggle_regex();
|
|
||||||
} else if let Some(flags) = &config.flags {
|
|
||||||
if let Some(regex) = flags.regex {
|
|
||||||
if regex {
|
|
||||||
app.process_search_state.search_toggle_regex();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_default_widget(matches: &clap::ArgMatches<'static>, config: &Config) -> app::WidgetPosition {
|
|
||||||
if matches.is_present("CPU_WIDGET") {
|
|
||||||
return app::WidgetPosition::Cpu;
|
|
||||||
} else if matches.is_present("MEM_WIDGET") {
|
|
||||||
return app::WidgetPosition::Mem;
|
|
||||||
} else if matches.is_present("DISK_WIDGET") {
|
|
||||||
return app::WidgetPosition::Disk;
|
|
||||||
} else if matches.is_present("TEMP_WIDGET") {
|
|
||||||
return app::WidgetPosition::Temp;
|
|
||||||
} else if matches.is_present("NET_WIDGET") {
|
|
||||||
return app::WidgetPosition::Network;
|
|
||||||
} else if matches.is_present("PROC_WIDGET") {
|
|
||||||
return app::WidgetPosition::Process;
|
|
||||||
} else if let Some(flags) = &config.flags {
|
|
||||||
if let Some(default_widget) = &flags.default_widget {
|
|
||||||
match default_widget.as_str() {
|
|
||||||
"cpu_default" => {
|
|
||||||
return app::WidgetPosition::Cpu;
|
|
||||||
}
|
|
||||||
"memory_default" => {
|
|
||||||
return app::WidgetPosition::Mem;
|
|
||||||
}
|
|
||||||
"processes_default" => {
|
|
||||||
return app::WidgetPosition::Process;
|
|
||||||
}
|
|
||||||
"network_default" => {
|
|
||||||
return app::WidgetPosition::Network;
|
|
||||||
}
|
|
||||||
"temperature_default" => {
|
|
||||||
return app::WidgetPosition::Temp;
|
|
||||||
}
|
|
||||||
"disk_default" => {
|
|
||||||
return app::WidgetPosition::Disk;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
app::WidgetPosition::Process
|
|
||||||
}
|
|
||||||
|
|
||||||
fn try_drawing(
|
fn try_drawing(
|
||||||
terminal: &mut tui::terminal::Terminal<tui::backend::CrosstermBackend<std::io::Stdout>>,
|
terminal: &mut tui::terminal::Terminal<tui::backend::CrosstermBackend<std::io::Stdout>>,
|
||||||
app: &mut App, painter: &mut canvas::Painter,
|
app: &mut App, painter: &mut canvas::Painter,
|
||||||
|
281
src/options.rs
Normal file
281
src/options.rs
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
app::{self, App, data_harvester},
|
||||||
|
constants::*,
|
||||||
|
utils::error::{self, BottomError},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Default, Deserialize)]
|
||||||
|
pub struct Config {
|
||||||
|
pub flags: Option<ConfigFlags>,
|
||||||
|
pub colors: Option<ConfigColours>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Deserialize)]
|
||||||
|
pub struct ConfigFlags {
|
||||||
|
pub 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 group_processes: Option<bool>,
|
||||||
|
pub case_sensitive: Option<bool>,
|
||||||
|
pub whole_word: Option<bool>,
|
||||||
|
pub regex: Option<bool>,
|
||||||
|
pub default_widget: Option<String>,
|
||||||
|
pub show_disabled_data: Option<bool>,
|
||||||
|
pub basic_mode: Option<bool>,
|
||||||
|
//disabled_cpu_cores: Option<Vec<u64>>, // TODO: [FEATURE] Enable disabling cores in config/flags
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Deserialize)]
|
||||||
|
pub struct ConfigColours {
|
||||||
|
pub table_header_color: Option<String>,
|
||||||
|
pub avg_cpu_color: Option<String>,
|
||||||
|
pub cpu_core_colors: Option<Vec<String>>,
|
||||||
|
pub ram_color: Option<String>,
|
||||||
|
pub swap_color: Option<String>,
|
||||||
|
pub rx_color: Option<String>,
|
||||||
|
pub tx_color: Option<String>,
|
||||||
|
pub rx_total_color: Option<String>,
|
||||||
|
pub tx_total_color: Option<String>,
|
||||||
|
pub border_color: Option<String>,
|
||||||
|
pub highlighted_border_color: Option<String>,
|
||||||
|
pub text_color: Option<String>,
|
||||||
|
pub selected_text_color: Option<String>,
|
||||||
|
pub selected_bg_color: Option<String>,
|
||||||
|
pub widget_title_color: Option<String>,
|
||||||
|
pub graph_color: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_update_rate_in_milliseconds(
|
||||||
|
update_rate: &Option<&str>, config: &Config,
|
||||||
|
) -> error::Result<u128> {
|
||||||
|
let update_rate_in_milliseconds = if let Some(update_rate) = update_rate {
|
||||||
|
update_rate.parse::<u128>()?
|
||||||
|
} else if let Some(flags) = &config.flags {
|
||||||
|
if let Some(rate) = flags.rate {
|
||||||
|
rate as u128
|
||||||
|
} else {
|
||||||
|
DEFAULT_REFRESH_RATE_IN_MILLISECONDS
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DEFAULT_REFRESH_RATE_IN_MILLISECONDS
|
||||||
|
};
|
||||||
|
|
||||||
|
if update_rate_in_milliseconds < 250 {
|
||||||
|
return Err(BottomError::InvalidArg(
|
||||||
|
"Please set your update rate to be greater than 250 milliseconds.".to_string(),
|
||||||
|
));
|
||||||
|
} else if update_rate_in_milliseconds > u128::from(std::u64::MAX) {
|
||||||
|
return Err(BottomError::InvalidArg(
|
||||||
|
"Please set your update rate to be less than unsigned INT_MAX.".to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(update_rate_in_milliseconds)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_temperature_option(
|
||||||
|
matches: &clap::ArgMatches<'static>, config: &Config,
|
||||||
|
) -> error::Result<data_harvester::temperature::TemperatureType> {
|
||||||
|
if matches.is_present("FAHRENHEIT") {
|
||||||
|
return Ok(data_harvester::temperature::TemperatureType::Fahrenheit);
|
||||||
|
} else if matches.is_present("KELVIN") {
|
||||||
|
return Ok(data_harvester::temperature::TemperatureType::Kelvin);
|
||||||
|
} else if matches.is_present("CELSIUS") {
|
||||||
|
return Ok(data_harvester::temperature::TemperatureType::Celsius);
|
||||||
|
} else if let Some(flags) = &config.flags {
|
||||||
|
if let Some(temp_type) = &flags.temperature_type {
|
||||||
|
// Give lowest priority to config.
|
||||||
|
return match temp_type.as_str() {
|
||||||
|
"fahrenheit" | "f" => {
|
||||||
|
Ok(data_harvester::temperature::TemperatureType::Fahrenheit)
|
||||||
|
}
|
||||||
|
"kelvin" | "k" => {
|
||||||
|
Ok(data_harvester::temperature::TemperatureType::Kelvin)
|
||||||
|
}
|
||||||
|
"celsius" | "c" => {
|
||||||
|
Ok(data_harvester::temperature::TemperatureType::Celsius)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
Err(BottomError::ConfigError(
|
||||||
|
"Invalid temperature type. Please have the value be of the form <kelvin|k|celsius|c|fahrenheit|f>".to_string()
|
||||||
|
))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(data_harvester::temperature::TemperatureType::Celsius)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_avg_cpu_option(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
|
||||||
|
if matches.is_present("AVG_CPU") {
|
||||||
|
return true;
|
||||||
|
} else if let Some(flags) = &config.flags {
|
||||||
|
if let Some(avg_cpu) = flags.avg_cpu {
|
||||||
|
return avg_cpu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_use_dot_option(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
|
||||||
|
if matches.is_present("DOT_MARKER") {
|
||||||
|
return true;
|
||||||
|
} else if let Some(flags) = &config.flags {
|
||||||
|
if let Some(dot_marker) = flags.dot_marker {
|
||||||
|
return dot_marker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_use_left_legend_option(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
|
||||||
|
if matches.is_present("LEFT_LEGEND") {
|
||||||
|
return true;
|
||||||
|
} else if let Some(flags) = &config.flags {
|
||||||
|
if let Some(left_legend) = flags.left_legend {
|
||||||
|
return left_legend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_use_current_cpu_total_option(
|
||||||
|
matches: &clap::ArgMatches<'static>, config: &Config,
|
||||||
|
) -> bool {
|
||||||
|
if matches.is_present("USE_CURR_USAGE") {
|
||||||
|
return true;
|
||||||
|
} else if let Some(flags) = &config.flags {
|
||||||
|
if let Some(current_usage) = flags.current_usage {
|
||||||
|
return current_usage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_show_disabled_data_option(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
|
||||||
|
if matches.is_present("SHOW_DISABLED_DATA") {
|
||||||
|
return true;
|
||||||
|
} else if let Some(flags) = &config.flags {
|
||||||
|
if let Some(show_disabled_data) = flags.show_disabled_data {
|
||||||
|
return show_disabled_data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_use_basic_mode_option(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
|
||||||
|
if matches.is_present("BASIC_MODE") {
|
||||||
|
return true;
|
||||||
|
} else if let Some(flags) = &config.flags {
|
||||||
|
if let Some(basic_mode) = flags.basic_mode {
|
||||||
|
return basic_mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn enable_app_grouping(matches: &clap::ArgMatches<'static>, config: &Config, app: &mut App) {
|
||||||
|
if matches.is_present("GROUP_PROCESSES") {
|
||||||
|
app.toggle_grouping();
|
||||||
|
} else if let Some(flags) = &config.flags {
|
||||||
|
if let Some(grouping) = flags.group_processes {
|
||||||
|
if grouping {
|
||||||
|
app.toggle_grouping();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn enable_app_case_sensitive(
|
||||||
|
matches: &clap::ArgMatches<'static>, config: &Config, app: &mut App,
|
||||||
|
) {
|
||||||
|
if matches.is_present("CASE_SENSITIVE") {
|
||||||
|
app.process_search_state.search_toggle_ignore_case();
|
||||||
|
} else if let Some(flags) = &config.flags {
|
||||||
|
if let Some(case_sensitive) = flags.case_sensitive {
|
||||||
|
if case_sensitive {
|
||||||
|
app.process_search_state.search_toggle_ignore_case();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn enable_app_match_whole_word(
|
||||||
|
matches: &clap::ArgMatches<'static>, config: &Config, app: &mut App,
|
||||||
|
) {
|
||||||
|
if matches.is_present("WHOLE_WORD") {
|
||||||
|
app.process_search_state.search_toggle_whole_word();
|
||||||
|
} else if let Some(flags) = &config.flags {
|
||||||
|
if let Some(whole_word) = flags.whole_word {
|
||||||
|
if whole_word {
|
||||||
|
app.process_search_state.search_toggle_whole_word();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn enable_app_use_regex(matches: &clap::ArgMatches<'static>, config: &Config, app: &mut App) {
|
||||||
|
if matches.is_present("REGEX_DEFAULT") {
|
||||||
|
app.process_search_state.search_toggle_regex();
|
||||||
|
} else if let Some(flags) = &config.flags {
|
||||||
|
if let Some(regex) = flags.regex {
|
||||||
|
if regex {
|
||||||
|
app.process_search_state.search_toggle_regex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_default_widget(
|
||||||
|
matches: &clap::ArgMatches<'static>, config: &Config,
|
||||||
|
) -> app::WidgetPosition {
|
||||||
|
if matches.is_present("CPU_WIDGET") {
|
||||||
|
return app::WidgetPosition::Cpu;
|
||||||
|
} else if matches.is_present("MEM_WIDGET") {
|
||||||
|
return app::WidgetPosition::Mem;
|
||||||
|
} else if matches.is_present("DISK_WIDGET") {
|
||||||
|
return app::WidgetPosition::Disk;
|
||||||
|
} else if matches.is_present("TEMP_WIDGET") {
|
||||||
|
return app::WidgetPosition::Temp;
|
||||||
|
} else if matches.is_present("NET_WIDGET") {
|
||||||
|
return app::WidgetPosition::Network;
|
||||||
|
} else if matches.is_present("PROC_WIDGET") {
|
||||||
|
return app::WidgetPosition::Process;
|
||||||
|
} else if let Some(flags) = &config.flags {
|
||||||
|
if let Some(default_widget) = &flags.default_widget {
|
||||||
|
match default_widget.as_str() {
|
||||||
|
"cpu_default" => {
|
||||||
|
return app::WidgetPosition::Cpu;
|
||||||
|
}
|
||||||
|
"memory_default" => {
|
||||||
|
return app::WidgetPosition::Mem;
|
||||||
|
}
|
||||||
|
"processes_default" => {
|
||||||
|
return app::WidgetPosition::Process;
|
||||||
|
}
|
||||||
|
"network_default" => {
|
||||||
|
return app::WidgetPosition::Network;
|
||||||
|
}
|
||||||
|
"temperature_default" => {
|
||||||
|
return app::WidgetPosition::Temp;
|
||||||
|
}
|
||||||
|
"disk_default" => {
|
||||||
|
return app::WidgetPosition::Disk;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
app::WidgetPosition::Process
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user