Update and clean up ? menu... some more work to be done though

This commit is contained in:
ClementTsang 2020-02-08 22:38:55 -05:00
parent b593a29e9c
commit 4ac3a10fbf
9 changed files with 142 additions and 115 deletions

View File

@ -23,7 +23,6 @@ lto = true
[dependencies]
chrono = "0.4.10"
clap = "2.33.0"
failure = "0.1.6"
fern = "0.5.9"
futures-timer = "3.0.1"
futures = "0.3.3"

View File

@ -195,7 +195,6 @@ Note that `q` is disabled while in the search widget.
- [chrono](https://github.com/chronotope/chrono)
- [clap](https://github.com/clap-rs/clap)
- [crossterm](https://github.com/TimonPost/crossterm)
- [failure](https://github.com/rust-lang-nursery/failure)
- [fern](https://github.com/daboross/fern)
- [futures-rs](https://github.com/rust-lang-nursery/futures-rs)
- [futures-timer](https://github.com/rustasync/futures-timer)
@ -204,6 +203,6 @@ Note that `q` is disabled while in the search widget.
- [log](https://github.com/rust-lang-nursery/log)
- [sysinfo](https://github.com/GuillaumeGomez/sysinfo)
- [tokio](https://github.com/tokio-rs/tokio)
- [toml-ru](https://github.com/alexcrichton/toml-rs)
- [toml-rs](https://github.com/alexcrichton/toml-rs)
- [tui-rs](https://github.com/fdehau/tui-rs)
- [winapi](https://github.com/retep998/winapi-rs)

View File

@ -1,7 +1,7 @@
[flags]
avg_cpu = true
dot_marker = true
temperature_type = "k"
temperature_type = "ke"
rate = 1000
left_legend = true
current_usage = false

View File

@ -37,12 +37,10 @@ fn cpu_usage_calculation(
let split_results = stat_results.split('\n').collect::<Vec<&str>>();
if split_results.is_empty() {
return Err(error::BottomError::InvalidIO {
message: format!(
"Unable to properly split the stat results; saw {} values, expected at least 1 value.",
split_results.len()
),
});
return Err(error::BottomError::InvalidIO(format!(
"Unable to properly split the stat results; saw {} values, expected at least 1 value.",
split_results.len()
)));
} else {
first_line = split_results[0];
}
@ -51,12 +49,10 @@ fn cpu_usage_calculation(
// SC in case that the parsing will fail due to length:
if val.len() <= 10 {
return Err(error::BottomError::InvalidIO {
message: format!(
return Err(error::BottomError::InvalidIO(format!(
"CPU parsing will fail due to too short of a return value; saw {} values, expected 10 values.",
val.len()
),
});
)));
}
let user: f64 = val[1].parse::<_>().unwrap_or(0_f64);

View File

@ -42,11 +42,10 @@ pub fn kill_process_given_pid(pid: u32) -> crate::utils::error::Result<()> {
process.kill()?;
}
} else {
return Err(BottomError::GenericError {
message:
"Sorry, support operating systems outside the main three are not implemented yet!"
.to_string(),
});
return Err(BottomError::GenericError(
"Sorry, support operating systems outside the main three are not implemented yet!"
.to_string(),
));
}
Ok(())

View File

@ -27,31 +27,78 @@ const WINDOWS_NETWORK_HEADERS: [&str; 4] = ["RX", "TX", "", ""];
const FORCE_MIN_THRESHOLD: usize = 5;
lazy_static! {
static ref HELP_TEXT: [Text<'static>; 22] = [
Text::raw("\nGeneral Keybindings\n"),
Text::raw("q, Ctrl-c to quit. Note if you are currently in the search widget, `q` will not work.\n"),
Text::raw("Ctrl-r to reset all data.\n"),
Text::raw("f to toggle freezing and unfreezing the display.\n"),
Text::raw(
"Ctrl/Shift-Up, Ctrl/Shift-Down, Ctrl/Shift-Left, and Ctrl/Shift-Right to navigate between widgets.\n"
static ref DEFAULT_TEXT_STYLE: Style = Style::default().fg(Color::Gray);
static ref DEFAULT_HEADER_STYLE: Style = Style::default().fg(Color::LightBlue);
static ref HELP_TEXT: [Text<'static>; 30] = [
Text::styled("\n General Keybindings\n", *DEFAULT_HEADER_STYLE),
Text::styled("q, Ctrl-c Quit\n", *DEFAULT_TEXT_STYLE),
Text::styled("Ctrl-r Reset all data\n", *DEFAULT_TEXT_STYLE),
Text::styled("f Freeze display\n", *DEFAULT_TEXT_STYLE),
Text::styled("Ctrl-Arrow Move selected widget\n", *DEFAULT_TEXT_STYLE),
Text::styled("Shift-Arrow Move selected widget\n", *DEFAULT_TEXT_STYLE),
Text::styled("Up, k Move cursor up\n", *DEFAULT_TEXT_STYLE),
Text::styled("Down, j Move cursor down\n", *DEFAULT_TEXT_STYLE),
Text::styled("Left, h Move cursor left\n", *DEFAULT_TEXT_STYLE),
Text::styled("Right, l Move cursor right\n", *DEFAULT_TEXT_STYLE),
Text::styled("Esc Close dialog box\n", *DEFAULT_TEXT_STYLE),
Text::styled("? Open the help screen\n", *DEFAULT_TEXT_STYLE),
Text::styled(
"gg Skip to the first entry of a list\n",
*DEFAULT_TEXT_STYLE
),
Text::raw("Up or k and Down or j scrolls through a list.\n"),
Text::raw("Esc to close a dialog window (help or dd confirmation).\n"),
Text::raw("? to get this help screen.\n"),
Text::raw("\n Process Widget Keybindings\n"),
Text::raw("dd to kill the selected process.\n"),
Text::raw("c to sort by CPU usage.\n"),
Text::raw("m to sort by memory usage.\n"),
Text::raw("p to sort by PID.\n"),
Text::raw("n to sort by process name.\n"),
Text::raw("Tab to group together processes with the same name.\n"),
Text::raw("Ctrl-f to toggle searching for a process. / to just open it.\n"),
Text::raw("Use Ctrl-p and Ctrl-n to toggle between searching for PID and name.\n"),
Text::raw("Use Tab to set the cursor to the start and end of the bar respectively.\n"),
Text::raw("Use Alt-c to toggle whether to ignore case.\n"),
Text::raw("Use Alt-m to toggle matching the entire word.\n"),
Text::raw("Use Alt-r to toggle regex.\n"),
Text::raw("\nFor startup flags, type in \"btm -h\".")
Text::styled(
"G Skip to the last entry of a list\n",
*DEFAULT_TEXT_STYLE
),
Text::styled(
"\n Process Keybindings\n",
*DEFAULT_HEADER_STYLE
),
Text::styled(
"dd Kill the highlighted process\n",
*DEFAULT_TEXT_STYLE
),
Text::styled("c Sort by CPU usage\n", *DEFAULT_TEXT_STYLE),
Text::styled("m Sort by memory usage\n", *DEFAULT_TEXT_STYLE),
Text::styled("p Sort by PID\n", *DEFAULT_TEXT_STYLE),
Text::styled("n Sort by process name\n", *DEFAULT_TEXT_STYLE),
Text::styled(
"Tab Group together processes with the same name\n",
*DEFAULT_TEXT_STYLE
),
Text::styled(
"Ctrl-f, / Open up the search widget\n",
*DEFAULT_TEXT_STYLE
),
Text::styled("\n Search Keybindings\n", *DEFAULT_HEADER_STYLE),
Text::styled(
"Tab Toggle between searching for PID and name.\n",
*DEFAULT_TEXT_STYLE
),
Text::styled(
"Ctrl-a Skip to the start of search widget\n",
*DEFAULT_TEXT_STYLE
),
Text::styled(
"Ctrl-e Skip to the end of search widget\n",
*DEFAULT_TEXT_STYLE
),
Text::styled(
"Alt-c Toggle whether to ignore case\n",
*DEFAULT_TEXT_STYLE
),
Text::styled(
"Alt-m Toggle whether to match the whole word\n",
*DEFAULT_TEXT_STYLE
),
Text::styled(
"Alt-r Toggle whether to use regex\n",
*DEFAULT_TEXT_STYLE
),
Text::styled(
"\n For startup flags, type in \"btm -h\".",
*DEFAULT_TEXT_STYLE
)
];
static ref DISK_HEADERS_LENS: Vec<usize> = DISK_HEADERS
.iter()
@ -129,9 +176,9 @@ impl Painter {
.margin(1)
.constraints(
[
Constraint::Percentage(22),
Constraint::Percentage(60),
Constraint::Percentage(18),
Constraint::Percentage(17),
Constraint::Percentage(70),
Constraint::Percentage(13),
]
.as_ref(),
)
@ -153,7 +200,7 @@ impl Painter {
Paragraph::new(HELP_TEXT.iter())
.block(
Block::default()
.title(" Help (Press Esc to close) ")
.title(" Help ")
.title_style(self.colours.widget_title_style)
.style(self.colours.border_style)
.borders(Borders::ALL),

View File

@ -60,12 +60,10 @@ pub fn convert_hex_to_color(hex: &str) -> error::Result<Color> {
return Ok((r, g, b));
}
Err(error::BottomError::GenericError {
message: format!(
Err(error::BottomError::GenericError(format!(
"Colour hex {} is not of valid length. It must be a 7 character string of the form \"#112233\".",
hex
),
})
)))
}
let rgb = convert_hex_to_rgb(hex)?;

View File

@ -3,8 +3,6 @@ extern crate log;
#[macro_use]
extern crate clap;
#[macro_use]
extern crate failure;
#[macro_use]
extern crate lazy_static;
use serde::Deserialize;
@ -153,13 +151,13 @@ fn main() -> error::Result<()> {
};
if update_rate_in_milliseconds < 250 {
return Err(BottomError::InvalidArg {
message: "Please set your update rate to be greater than 250 milliseconds.".to_string(),
});
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 {
message: "Please set your update rate to be less than unsigned INT_MAX.".to_string(),
});
return Err(BottomError::InvalidArg(
"Please set your update rate to be less than unsigned INT_MAX.".to_string(),
));
}
// Set other settings
@ -176,7 +174,11 @@ fn main() -> error::Result<()> {
"fahrenheit" | "f" => data_harvester::temperature::TemperatureType::Fahrenheit,
"kelvin" | "k" => data_harvester::temperature::TemperatureType::Kelvin,
"celsius" | "c" => data_harvester::temperature::TemperatureType::Celsius,
_ => data_harvester::temperature::TemperatureType::Celsius,
_ => {
return Err(BottomError::ConfigError(
"Invalid temperature type. Please have the value be of the form <kelvin|k|celsius|c|fahrenheit|f>".to_string()
));
}
}
} else {
data_harvester::temperature::TemperatureType::Celsius

View File

@ -1,102 +1,89 @@
use failure::Fail;
use std::result;
/// A type alias for handling errors related to Bottom.
pub type Result<T> = result::Result<T, BottomError>;
/// An error that can occur while Bottom runs.
#[derive(Debug, Fail)]
#[derive(Debug)]
pub enum BottomError {
/// An error when there is an IO exception.
///
/// The data provided is the error found.
#[fail(display = "ERROR: Encountered an IO exception: {}", message)]
InvalidIO { message: String },
InvalidIO(String),
/// An error when there is an invalid argument passed in.
///
/// The data provided is the error found.
#[fail(display = "ERROR: Invalid argument: {}", message)]
InvalidArg { message: String },
InvalidArg(String),
/// An error when the heim library encounters a problem.
///
/// The data provided is the error found.
#[fail(
display = "ERROR: Invalid error during data collection due to Heim: {}",
message
)]
InvalidHeim { message: String },
InvalidHeim(String),
/// An error when the Crossterm library encounters a problem.
///
/// The data provided is the error found.
#[fail(display = "ERROR: Invalid error due to Crossterm: {}", message)]
CrosstermError { message: String },
/// An error to represent generic errors
///
/// The data provided is the error found.
#[fail(display = "ERROR: Invalid generic error: {}", message)]
GenericError { message: String },
/// An error to represent errors with fern
///
/// 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 },
CrosstermError(String),
/// An error to represent generic errors.
GenericError(String),
/// An error to represent errors with fern.
FernError(String),
/// An error to represent errors with the config.
ConfigError(String),
}
impl std::fmt::Display for BottomError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match *self {
BottomError::InvalidIO(ref message) => {
write!(f, "Encountered an IO exception: {}", message)
}
BottomError::InvalidArg(ref message) => write!(f, "Invalid argument: {}", message),
BottomError::InvalidHeim(ref message) => write!(
f,
"Invalid error during data collection due to Heim: {}",
message
),
BottomError::CrosstermError(ref message) => {
write!(f, "Invalid error due to Crossterm: {}", message)
}
BottomError::GenericError(ref message) => write!(f, "{}", message),
BottomError::FernError(ref message) => write!(f, "Invalid fern error: {}", message),
BottomError::ConfigError(ref message) => {
write!(f, "Invalid config file error: {}", message)
}
}
}
}
impl From<std::io::Error> for BottomError {
fn from(err: std::io::Error) -> Self {
BottomError::InvalidIO {
message: err.to_string(),
}
BottomError::InvalidIO(err.to_string())
}
}
impl From<heim::Error> for BottomError {
fn from(err: heim::Error) -> Self {
BottomError::InvalidHeim {
message: err.to_string(),
}
BottomError::InvalidHeim(err.to_string())
}
}
impl From<crossterm::ErrorKind> for BottomError {
fn from(err: crossterm::ErrorKind) -> Self {
BottomError::CrosstermError {
message: err.to_string(),
}
BottomError::CrosstermError(err.to_string())
}
}
impl From<std::num::ParseIntError> for BottomError {
fn from(err: std::num::ParseIntError) -> Self {
BottomError::InvalidArg {
message: err.to_string(),
}
BottomError::InvalidArg(err.to_string())
}
}
impl From<std::string::String> for BottomError {
fn from(err: std::string::String) -> Self {
BottomError::GenericError { message: err }
BottomError::GenericError(err)
}
}
impl From<toml::de::Error> for BottomError {
fn from(err: toml::de::Error) -> Self {
BottomError::ConfigError {
message: err.to_string(),
}
BottomError::ConfigError(err.to_string())
}
}
impl From<fern::InitError> for BottomError {
fn from(err: fern::InitError) -> Self {
BottomError::FernError {
message: err.to_string(),
}
BottomError::FernError(err.to_string())
}
}