summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorClementTsang <cjhtsang@uwaterloo.ca>2020-02-06 23:58:33 -0500
committerClementTsang <cjhtsang@uwaterloo.ca>2020-02-07 00:16:41 -0500
commit96d405a3536884e9046972d5d413aa61b3bec2ec (patch)
treed89933838f1eafcc669a0a824b57f4d8f629d3e6 /src
parentfc37cf7f3dccaae6065a81ad5cfc869e9f74c23f (diff)
Add config options
Diffstat (limited to 'src')
-rw-r--r--src/constants.rs7
-rw-r--r--src/main.rs111
-rw-r--r--src/utils/error.rs13
3 files changed, 115 insertions, 16 deletions
diff --git a/src/constants.rs b/src/constants.rs
index b512f0a1..2dbb546d 100644
--- a/src/constants.rs
+++ b/src/constants.rs
@@ -4,3 +4,10 @@ pub const TICK_RATE_IN_MILLISECONDS: u64 = 200; // How fast the screen refreshes
pub const DEFAULT_REFRESH_RATE_IN_MILLISECONDS: u128 = 1000;
pub const MAX_KEY_TIMEOUT_IN_MILLISECONDS: u128 = 1000;
pub const NUM_COLOURS: i32 = 256;
+
+// Config and flags
+pub const DEFAULT_CONFIG_FILE_PATH: &str = "~/.config/btm/btm.conf";
+
+pub const KELVIN: &str = "kelvin";
+pub const FAHRENHEIT: &str = "fahrenheit";
+pub const CELSIUS: &str = "celsius";
diff --git a/src/main.rs b/src/main.rs
index 41addd79..fdf81072 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -7,6 +7,8 @@ extern crate failure;
#[macro_use]
extern crate lazy_static;
+use serde::Deserialize;
+
use crossterm::{
event::{
poll, read, DisableMouseCapture, EnableMouseCapture, Event as CEvent, KeyCode,
@@ -38,7 +40,7 @@ mod constants;
mod data_conversion;
use app::data_harvester::{self, processes::ProcessSorting};
-use constants::TICK_RATE_IN_MILLISECONDS;
+use constants::*;
use data_conversion::*;
use utils::error::{self, BottomError};
@@ -53,8 +55,22 @@ enum ResetEvent {
Reset,
}
+#[derive(Deserialize)]
+struct Config {
+ 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>,
+}
+
fn main() -> error::Result<()> {
- // Parse command line options
+ //Parse command line options
let matches = clap_app!(app =>
(name: crate_name!())
(version: crate_version!())
@@ -62,7 +78,6 @@ fn main() -> error::Result<()> {
(about: crate_description!())
(@arg AVG_CPU: -a --avg_cpu "Enables showing the average CPU usage.")
(@arg DOT_MARKER: -m --dot_marker "Use a dot marker instead of the default braille marker.")
- (@arg DEBUG: -d --debug "Enables debug mode, which will output a log file.")
(@group TEMPERATURE_TYPE =>
(@arg KELVIN : -k --kelvin "Sets the temperature type to Kelvin.")
(@arg FAHRENHEIT : -f --fahrenheit "Sets the temperature type to Fahrenheit.")
@@ -71,20 +86,39 @@ fn main() -> error::Result<()> {
(@arg RATE_MILLIS: -r --rate +takes_value "Sets a refresh rate in milliseconds; the minimum is 250ms, defaults to 1000ms. Smaller values may take more resources.")
(@arg LEFT_LEGEND: -l --left_legend "Puts external chart legends on the left side rather than the default right side.")
(@arg USE_CURR_USAGE: -u --current_usage "Within Linux, sets a process' CPU usage to be based on the total current CPU usage, rather than assuming 100% usage.")
- //(@arg CONFIG_LOCATION: -co --config +takes_value "Sets the location of the config file. Expects a config file in the JSON format.")
+ (@arg CONFIG_LOCATION: -C --config +takes_value "Sets the location of the config file. Expects a config file in the TOML format.")
//(@arg BASIC_MODE: -b --basic "Sets bottom to basic mode, not showing graphs and only showing basic tables.")
(@arg GROUP_PROCESSES: -g --group "Groups processes with the same name together on launch.")
(@arg CASE_SENSITIVE: -S --case_sensitive "Match case when searching by default.")
- (@arg WHOLE_WORD: -W --whole "Match whole word when searching by default.")
+ (@arg WHOLE_WORD: -W --whole_word "Match whole word when searching by default.")
(@arg REGEX_DEFAULT: -R --regex "Use regex in searching by default.")
)
.get_matches();
+ if cfg!(debug_assertions) {
+ utils::logging::init_logger()?;
+ }
+
+ let config_path = std::path::Path::new(
+ matches
+ .value_of("CONFIG_LOCATION")
+ .unwrap_or(DEFAULT_CONFIG_FILE_PATH),
+ );
+
+ let config_string = std::fs::read_to_string(config_path);
+ let config_toml: Config = if let Ok(config_str) = config_string {
+ toml::from_str(&config_str)?
+ } else {
+ toml::from_str("")?
+ };
+
let update_rate_in_milliseconds: u128 = if matches.is_present("RATE_MILLIS") {
matches
.value_of("RATE_MILLIS")
- .unwrap_or(&constants::DEFAULT_REFRESH_RATE_IN_MILLISECONDS.to_string())
+ .unwrap_or(&DEFAULT_REFRESH_RATE_IN_MILLISECONDS.to_string())
.parse::<u128>()?
+ } else if let Some(rate) = config_toml.rate {
+ rate as u128
} else {
constants::DEFAULT_REFRESH_RATE_IN_MILLISECONDS
};
@@ -99,24 +133,53 @@ fn main() -> error::Result<()> {
});
}
- // Attempt to create debugging...
- let enable_debugging = matches.is_present("DEBUG");
- if enable_debugging || cfg!(debug_assertions) {
- utils::logging::init_logger()?;
- }
-
// Set other settings
let temperature_type = if matches.is_present("FAHRENHEIT") {
data_harvester::temperature::TemperatureType::Fahrenheit
} else if matches.is_present("KELVIN") {
data_harvester::temperature::TemperatureType::Kelvin
+ } else if matches.is_present("CELSIUS") {
+ data_harvester::temperature::TemperatureType::Celsius
+ } else if let Some(temp_type) = config_toml.temperature_type {
+ // Give lowest priority to config.
+ match temp_type.as_str() {
+ constants::FAHRENHEIT => data_harvester::temperature::TemperatureType::Fahrenheit,
+ constants::KELVIN => data_harvester::temperature::TemperatureType::Kelvin,
+ constants::CELSIUS => data_harvester::temperature::TemperatureType::Celsius,
+ _ => data_harvester::temperature::TemperatureType::Celsius,
+ }
} else {
data_harvester::temperature::TemperatureType::Celsius
};
- let show_average_cpu = matches.is_present("AVG_CPU");
- let use_dot = matches.is_present("DOT_MARKER");
- let left_legend = matches.is_present("LEFT_LEGEND");
- let use_current_cpu_total = matches.is_present("USE_CURR_USAGE");
+ let show_average_cpu = if matches.is_present("AVG_CPU") {
+ true
+ } else if let Some(avg_cpu) = config_toml.avg_cpu {
+ avg_cpu
+ } else {
+ false
+ };
+ let use_dot = if matches.is_present("DOT_MARKER") {
+ true
+ } else if let Some(dot_marker) = config_toml.dot_marker {
+ dot_marker
+ } else {
+ false
+ };
+ let left_legend = if matches.is_present("LEFT_LEGEND") {
+ true
+ } else if let Some(left_legend) = config_toml.left_legend {
+ left_legend
+ } else {
+ false
+ };
+
+ let use_current_cpu_total = if matches.is_present("USE_CURR_USAGE") {
+ true
+ } else if let Some(current_usage) = config_toml.current_usage {
+ current_usage
+ } else {
+ false
+ };
// Create "app" struct, which will control most of the program and store settings/state
let mut app = app::App::new(
@@ -131,19 +194,35 @@ fn main() -> error::Result<()> {
// Enable grouping immediately if set.
if matches.is_present("GROUP_PROCESSES") {
app.toggle_grouping();
+ } else if let Some(grouping) = config_toml.group_processes {
+ if grouping {
+ app.toggle_grouping();
+ }
}
// Set default search method
if matches.is_present("CASE_SENSITIVE") {
app.search_state.toggle_ignore_case();
+ } else if let Some(case_sensitive) = config_toml.case_sensitive {
+ if case_sensitive {
+ app.search_state.toggle_ignore_case();
+ }
}
if matches.is_present("WHOLE_WORD") {
app.search_state.toggle_search_whole_word();
+ } else if let Some(whole_word) = config_toml.whole_word {
+ if whole_word {
+ app.search_state.toggle_search_whole_word();
+ }
}
if matches.is_present("REGEX_DEFAULT") {
app.search_state.toggle_search_regex();
+ } else if let Some(regex) = config_toml.regex {
+ if regex {
+ app.search_state.toggle_search_regex();
+ }
}
// Set up up tui and crossterm
diff --git a/src/utils/error.rs b/src/utils/error.rs
index 145f6684..2383acf9 100644
--- a/src/utils/error.rs
+++ b/src/utils/error.rs
@@ -40,6 +40,11 @@ pub enum BottomError {
/// The data provided is the error found.
#[fail(display = "ERROR: Invalid fern error: {}", message)]
FernError { message: String },
+ /// An error to represent errors with fern
+ ///
+ /// The data provided is the error found.
+ #[fail(display = "ERROR: Invalid config file error: {}", message)]
+ ConfigError { message: String },
}
impl From<std::io::Error> for BottomError {
@@ -80,6 +85,14 @@ impl From<std::string::String> for BottomError {
}
}
+impl From<toml::de::Error> for BottomError {
+ fn from(err: toml::de::Error) -> Self {
+ BottomError::ConfigError {
+ message: err.to_string(),
+ }
+ }
+}
+
impl From<fern::InitError> for BottomError {
fn from(err: fern::InitError) -> Self {
BottomError::FernError {