summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClementTsang <34804052+ClementTsang@users.noreply.github.com>2024-06-01 03:01:57 -0400
committerClementTsang <34804052+ClementTsang@users.noreply.github.com>2024-06-01 03:01:57 -0400
commit78e96ba1d6e3f3bdd8f9154a8bed2198f1be961b (patch)
treefde427873f385d743dbcb3510d0f3509ed092e88
parentee2e1fee1c6758ee0ec33af28f9d51f1c423599e (diff)
refactor: sort out some error handlingunify_quote_err
-rw-r--r--src/app.rs5
-rw-r--r--src/app/layout_manager.rs10
-rw-r--r--src/app/process_killer.rs6
-rw-r--r--src/app/query.rs42
-rw-r--r--src/canvas.rs6
-rw-r--r--src/canvas/styling/colour_utils.rs52
-rw-r--r--src/data_collection/disks/unix/linux/partition.rs7
-rw-r--r--src/data_collection/disks/unix/other/partition.rs3
-rw-r--r--src/data_collection/processes.rs2
-rw-r--r--src/data_collection/processes/linux.rs13
-rw-r--r--src/data_collection/processes/unix/user_table.rs6
-rw-r--r--src/data_collection/temperature/linux.rs10
-rw-r--r--src/lib.rs8
-rw-r--r--src/options.rs165
-rw-r--r--src/options/config/layout.rs11
-rw-r--r--src/utils/error.rs107
-rw-r--r--src/utils/error/collection.rs46
-rw-r--r--src/utils/error/config.rs47
-rw-r--r--src/utils/error/draw.rs14
19 files changed, 326 insertions, 234 deletions
diff --git a/src/app.rs b/src/app.rs
index 11cd358b..b08691f5 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -1406,9 +1406,8 @@ impl App {
self.to_delete_process_list = None;
Ok(())
} else {
- Err(BottomError::GenericError(
- "Cannot kill processes if the current widget is not the Process widget!"
- .to_string(),
+ Err(BottomError::user(
+ "Cannot kill processes if the current widget is not the Process widget!",
))
}
}
diff --git a/src/app/layout_manager.rs b/src/app/layout_manager.rs
index e7904c9a..3e4ec84f 100644
--- a/src/app/layout_manager.rs
+++ b/src/app/layout_manager.rs
@@ -2,7 +2,7 @@ use std::collections::BTreeMap;
use crate::{
constants::DEFAULT_WIDGET_ID,
- error::{BottomError, Result},
+ utils::error::{ConfigError, ConfigResult},
};
/// Represents a more usable representation of the layout, derived from the
@@ -985,9 +985,9 @@ impl BottomWidgetType {
}
impl std::str::FromStr for BottomWidgetType {
- type Err = BottomError;
+ type Err = ConfigError;
- fn from_str(s: &str) -> Result<Self> {
+ fn from_str(s: &str) -> ConfigResult<Self> {
let lower_case = s.to_lowercase();
match lower_case.as_str() {
"cpu" => Ok(BottomWidgetType::Cpu),
@@ -1002,7 +1002,7 @@ impl std::str::FromStr for BottomWidgetType {
_ => {
#[cfg(feature = "battery")]
{
- Err(BottomError::ConfigError(format!(
+ Err(ConfigError::other(format!(
"\"{s}\" is an invalid widget name.
Supported widget names:
@@ -1028,7 +1028,7 @@ Supported widget names:
}
#[cfg(not(feature = "battery"))]
{
- Err(BottomError::ConfigError(format!(
+ Err(BottomError::config(format!(
"\"{s}\" is an invalid widget name.
Supported widget names:
diff --git a/src/app/process_killer.rs b/src/app/process_killer.rs
index c68b81ab..df846a33 100644
--- a/src/app/process_killer.rs
+++ b/src/app/process_killer.rs
@@ -74,11 +74,9 @@ pub fn kill_process_given_pid(pid: Pid, signal: usize) -> crate::utils::error::R
};
return if let Some(err_code) = err_code {
- Err(BottomError::GenericError(format!(
- "Error code {err_code} - {err}"
- )))
+ Err(BottomError::user(format!("Error code {err_code} - {err}")))
} else {
- Err(BottomError::GenericError(format!("Error code ??? - {err}")))
+ Err(BottomError::user(format!("Error code ??? - {err}")))
};
}
diff --git a/src/app/query.rs b/src/app/query.rs
index 5737cbc7..81e6efcf 100644
--- a/src/app/query.rs
+++ b/src/app/query.rs
@@ -1,5 +1,4 @@
use std::{
- borrow::Cow,
collections::VecDeque,
fmt::{Debug, Formatter},
time::Duration,
@@ -13,10 +12,7 @@ use crate::{
multi_eq_ignore_ascii_case,
utils::{
data_prefixes::*,
- error::{
- BottomError::{self, QueryError},
- Result,
- },
+ error::{BottomError, Result},
},
};
@@ -86,7 +82,7 @@ pub fn parse_query(
break;
}
} else if COMPARISON_LIST.contains(&current_lowercase.as_str()) {
- return Err(QueryError(Cow::Borrowed("Comparison not valid here")));
+ return Err(BottomError::user("Comparison not valid here"));
} else {
break;
}
@@ -125,7 +121,7 @@ pub fn parse_query(
break;
}
} else if COMPARISON_LIST.contains(&current_lowercase.as_str()) {
- return Err(QueryError(Cow::Borrowed("Comparison not valid here")));
+ return Err(BottomError::user("Comparison not valid here"));
} else {
break;
}
@@ -206,7 +202,7 @@ pub fn parse_query(
}
} else if queue_top == "(" {
if query.is_empty() {
- return Err(QueryError(Cow::Borrowed("Missing closing parentheses")));
+ return Err(BottomError::user("Missing closing parentheses"));
}
let mut list_of_ors = VecDeque::new();
@@ -221,7 +217,7 @@ pub fn parse_query(
// Ensure not empty
if list_of_ors.is_empty() {
- return Err(QueryError("No values within parentheses group".into()));
+ return Err(BottomError::user("No values within parentheses group"));
}
// Now convert this back to a OR...
@@ -260,13 +256,13 @@ pub fn parse_query(
compare_prefix: None,
});
} else {
- return Err(QueryError("Missing closing parentheses".into()));
+ return Err(BottomError::user("Missing closing parentheses"));
}
} else {
- return Err(QueryError("Missing closing parentheses".into()));
+ return Err(BottomError::user("Missing closing parentheses"));
}
} else if queue_top == ")" {
- return Err(QueryError("Missing opening parentheses".into()));
+ return Err(BottomError::user("Missing opening parentheses"));
} else if queue_top == "\"" {
// Similar to parentheses, trap and check for missing closing quotes. Note, however, that we
// will DIRECTLY call another process_prefix call...
@@ -276,10 +272,10 @@ pub fn parse_query(
if close_paren == "\"" {
return Ok(prefix);
} else {
- return Err(QueryError("Missing closing quotation".into()));
+ return Err(BottomError::user("Missing closing quotation"));
}
} else {
- return Err(QueryError("Missing closing quotation".into()));
+ return Err(BottomError::user("Missing closing quotation"));
}
} else {
// Get prefix type...
@@ -355,15 +351,15 @@ pub fn parse_query(
duration_string = Some(queue_next);
}
} else {
- return Err(QueryError("Missing value".into()));
+ return Err(BottomError::user("Missing value"));
}
}
if let Some(condition) = condition {
let duration = parse_duration(
- &duration_string.ok_or(QueryError("Missing value".into()))?,
+ &duration_string.ok_or(BottomError::user("Missing value"))?,
)
- .map_err(|err| QueryError(err.to_string().into()))?;
+ .map_err(|err| BottomError::user(err.to_string()))?;
return Ok(Prefix {
or: None,
@@ -392,7 +388,7 @@ pub fn parse_query(
if let Some(queue_next) = query.pop_front() {
value = queue_next.parse::<f64>().ok();
} else {
- return Err(QueryError("Missing value".into()));
+ return Err(BottomError::user("Missing value"));
}
} else if content == ">" || content == "<" {
// We also have to check if the next string is an "="...
@@ -406,7 +402,7 @@ pub fn parse_query(
if let Some(queue_next_next) = query.pop_front() {
value = queue_next_next.parse::<f64>().ok();
} else {
- return Err(QueryError("Missing value".into()));
+ return Err(BottomError::user("Missing value"));
}
} else {
condition = Some(if content == ">" {
@@ -417,7 +413,7 @@ pub fn parse_query(
value = queue_next.parse::<f64>().ok();
}
} else {
- return Err(QueryError("Missing value".into()));
+ return Err(BottomError::user("Missing value"));
}
}
@@ -459,15 +455,15 @@ pub fn parse_query(
}
}
} else {
- return Err(QueryError("Missing argument for search prefix".into()));
+ return Err(BottomError::user("Missing argument for search prefix"));
}
}
} else if inside_quotation {
// Uh oh, it's empty with quotes!
- return Err(QueryError("Missing closing quotation".into()));
+ return Err(BottomError::user("Missing closing quotation"));
}
- Err(QueryError("Invalid query".into()))
+ Err(BottomError::user("Invalid query"))
}
let mut split_query = VecDeque::new();
diff --git a/src/canvas.rs b/src/canvas.rs
index ca144c15..91529075 100644
--- a/src/canvas.rs
+++ b/src/canvas.rs
@@ -48,7 +48,7 @@ impl FromStr for ColourScheme {
"gruvbox-light" => Ok(ColourScheme::GruvboxLight),
"nord" => Ok(ColourScheme::Nord),
"nord-light" => Ok(ColourScheme::NordLight),
- _ => Err(BottomError::ConfigError(format!(
+ _ => Err(BottomError::config(format!(
"`{s}` is an invalid built-in color scheme."
))),
}
@@ -81,7 +81,7 @@ pub enum LayoutConstraint {
}
impl Painter {
- pub fn init(layout: BottomLayout, styling: CanvasStyling) -> anyhow::Result<Self> {
+ pub fn init(layout: BottomLayout, styling: CanvasStyling) -> error::Result<Self> {
// Now for modularity; we have to also initialize the base layouts!
// We want to do this ONCE and reuse; after this we can just construct
// based on the console size.
@@ -204,7 +204,7 @@ impl Painter {
pub fn draw_data<B: Backend>(
&mut self, terminal: &mut Terminal<B>, app_state: &mut App,
- ) -> error::Result<()> {
+ ) -> error::DrawResult<()> {
use BottomWidgetType::*;
terminal.draw(|f| {
diff --git a/src/canvas/styling/colour_utils.rs b/src/canvas/styling/colour_utils.rs
index 1c1def3e..acaee373 100644
--- a/src/canvas/styling/colour_utils.rs
+++ b/src/canvas/styling/colour_utils.rs
@@ -3,7 +3,7 @@ use itertools::Itertools;
use tui::style::{Color, Style};
use unicode_segmentation::UnicodeSegmentation;
-use crate::utils::error;
+use crate::utils::error::{self, BottomError};
pub const FIRST_COLOUR: Color = Color::LightMagenta;
pub const SECOND_COLOUR: Color = Color::LightYellow;
@@ -19,14 +19,14 @@ pub const ALL_COLOUR: Color = Color::Green;
fn convert_hex_to_color(hex: &str) -> error::Result<Color> {
fn hex_component_to_int(hex: &str, first: &str, second: &str) -> error::Result<u8> {
u8::from_str_radix(&concat_string!(first, second), 16).map_err(|_| {
- error::BottomError::ConfigError(format!(
+ BottomError::config(format!(
"\"{hex}\" is an invalid hex color, could not decode."
))
})
}
- fn invalid_hex_format(hex: &str) -> error::BottomError {
- error::BottomError::ConfigError(format!(
+ fn invalid_hex_format(hex: &str) -> BottomError {
+ BottomError::config(format!(
"\"{hex}\" is an invalid hex color. It must be either a 7 character hex string of the form \"#12ab3c\" or a 3 character hex string of the form \"#1a2\".",
))
}
@@ -69,7 +69,7 @@ pub fn str_to_colour(input_val: &str) -> error::Result<Color> {
convert_name_to_colour(input_val)
}
} else {
- Err(error::BottomError::ConfigError(format!(
+ Err(BottomError::config(format!(
"value \"{input_val}\" is not valid.",
)))
}
@@ -78,7 +78,7 @@ pub fn str_to_colour(input_val: &str) -> error::Result<Color> {
fn convert_rgb_to_color(rgb_str: &str) -> error::Result<Color> {
let rgb_list = rgb_str.split(',').collect::<Vec<&str>>();
if rgb_list.len() != 3 {
- return Err(error::BottomError::ConfigError(format!(
+ return Err(BottomError::config(format!(
"value \"{rgb_str}\" is an invalid RGB colour. It must be a comma separated value with 3 integers from 0 to 255 (ie: \"255, 0, 155\").",
)));
}
@@ -96,7 +96,7 @@ fn convert_rgb_to_color(rgb_str: &str) -> error::Result<Color> {
if rgb.len() == 3 {
Ok(Color::Rgb(rgb[0], rgb[1], rgb[2]))
} else {
- Err(error::BottomError::ConfigError(format!(
+ Err(BottomError::config(format!(
"value \"{rgb_str}\" contained invalid RGB values. It must be a comma separated value with 3 integers from 0 to 255 (ie: \"255, 0, 155\").",
)))
}
@@ -121,7 +121,7 @@ fn convert_name_to_colour(color_name: &str) -> error::Result<Color> {
"lightmagenta" | "light magenta" => Ok(Color::LightMagenta),
"lightcyan" | "light cyan" => Ok(Color::LightCyan),
"white" => Ok(Color::White),
- _ => Err(error::BottomError::ConfigError(format!(
+ _ => Err(BottomError::config(format!(
"\"{color_name}\" is an invalid named color.
The following are supported strings:
@@ -177,35 +177,41 @@ mod test {
#[test]
fn valid_colour_names() {
// Standard color should work
- assert_eq!(convert_name_to_colour("red"), Ok(Color::Red));
+ assert_eq!(convert_name_to_colour("red").unwrap(), Color::Red);
// Capitalizing should be fine.
- assert_eq!(convert_name_to_colour("RED"), Ok(Color::Red));
+ assert_eq!(convert_name_to_colour("RED").unwrap(), Color::Red);
// Spacing shouldn't be an issue now.
- assert_eq!(convert_name_to_colour(" red "), Ok(Color::Red));
+ assert_eq!(convert_name_to_colour(" red ").unwrap(), Color::Red);
// The following are all equivalent.
- assert_eq!(convert_name_to_colour("darkgray"), Ok(Color::DarkGray));
- assert_eq!(convert_name_to_colour("darkgrey"), Ok(Color::DarkGray));
- assert_eq!(convert_name_to_colour("dark grey"), Ok(Color::DarkGray));
- assert_eq!(convert_name_to_colour("dark gray"), Ok(Color::DarkGray));
+ assert_eq!(convert_name_to_colour("darkgray").unwrap(), Color::DarkGray);
+ assert_eq!(convert_name_to_colour("darkgrey").unwrap(), Color::DarkGray);
+ assert_eq!(
+ convert_name_to_colour("dark grey").unwrap(),
+ Color::DarkGray
+ );
+ assert_eq!(
+ convert_name_to_colour("dark gray").unwrap(),
+ Color::DarkGray
+ );
- assert_eq!(convert_name_to_colour("grey"), Ok(Color::Gray));
- assert_eq!(convert_name_to_colour("gray"), Ok(Color::Gray));
+ assert_eq!(convert_name_to_colour("grey").unwrap(), Color::Gray);
+ assert_eq!(convert_name_to_colour("gray").unwrap(), Color::Gray);
// One more test with spacing.
assert_eq!(
- convert_name_to_colour(" lightmagenta "),
- Ok(Color::LightMagenta)
+ convert_name_to_colour(" lightmagenta ").unwrap(),
+ Color::LightMagenta
);
assert_eq!(
- convert_name_to_colour("light magenta"),
- Ok(Color::LightMagenta)
+ convert_name_to_colour("light magenta").unwrap(),
+ Color::LightMagenta
);
assert_eq!(
- convert_name_to_colour(" light magenta "),
- Ok(Color::LightMagenta)
+ convert_name_to_colour(" light magenta ").unwrap(),
+ Color::LightMagenta
);
}
diff --git a/src/data_collection/disks/unix/linux/partition.rs b/src/data_collection/disks/unix/linux/partition.rs
index 488ad8d9..1d8a0008 100644
--- a/src/data_collection/disks/unix/linux/partition.rs
+++ b/src/data_collection/disks/unix/linux/partition.rs
@@ -12,7 +12,10 @@ use std::{
use anyhow::bail;
-use crate::data_collection::disks::unix::{FileSystem, Usage};
+use crate::{
+ data_collection::disks::unix::{FileSystem, Usage},
+ utils::error,
+};
/// Representation of partition details. Based on [`heim`](https://github.com/heim-rs/heim/tree/master).
pub(crate) struct Partition {
@@ -164,7 +167,7 @@ pub(crate) fn partitions() -> anyhow::Result<Vec<Partition>> {
/// Returns a [`Vec`] containing all *physical* partitions. This is defined by
/// [`FileSystem::is_physical()`].
-pub(crate) fn physical_partitions() -> anyhow::Result<Vec<Partition>> {
+pub(crate) fn physical_partitions() -> error::CollectionResult<Vec<Partition>> {
const PROC_MOUNTS: &str = "/proc/mounts";
let mut results = vec![];
diff --git a/src/data_collection/disks/unix/other/partition.rs b/src/data_collection/disks/unix/other/partition.rs
index 1e64a70d..78420717 100644
--- a/src/data_collection/disks/unix/other/partition.rs
+++ b/src/data_collection/disks/unix/other/partition.rs
@@ -2,6 +2,7 @@ use std::{
ffi::{CStr, CString},
os::unix::prelude::OsStrExt,
path::{Path, PathBuf},
+ std::mem::MaybeUninit,
str::FromStr,
};
@@ -32,7 +33,7 @@ impl Partition {
/// Returns the usage stats for this partition.
pub fn usage(&self) -> anyhow::Result<Usage> {
let path = CString::new(self.mount_point().as_os_str().as_bytes())?;
- let mut vfs = std::mem::MaybeUninit::<libc::statvfs>::uninit();
+ let mut vfs = MaybeUninit::<libc::statvfs>::uninit();
// SAFETY: System API call. Arguments should be correct.
let result = unsafe { libc::statvfs(path.as_ptr(), vfs.as_mut_ptr()) };
diff --git a/src/data_collection/processes.rs b/src/data_collection/processes.rs
index ef96c818..80f84ed1 100644
--- a/src/data_collection/processes.rs
+++ b/src/data_collection/processes.rs
@@ -120,7 +120,7 @@ impl ProcessHarvest {
}
impl DataCollector {
- pub(crate) fn get_processes(&mut self) -> error::Result<Vec<ProcessHarvest>> {
+ pub(crate) fn get_processes(&mut self) -> error::CollectionResult<Vec<ProcessHarvest>> {
cfg_if! {
if #[cfg(target_os = "linux")] {
let time_diff = self.data.collection_time
diff --git a/src/data_collection/processes/linux.rs b/src/data_collection/processes/linux.rs
index 5d99fbbc..4065b076 100644
--- a/src/data_collection/processes/linux.rs
+++ b/src/data_collection/processes/linux.rs
@@ -15,7 +15,7 @@ use sysinfo::ProcessStatus;
use super::{ProcessHarvest, UserTable};
use crate::{
data_collection::DataCollector,
- utils::error::{self, BottomError},
+ utils::error::{self, CollectionError},
Pid,
};
@@ -65,7 +65,9 @@ struct CpuUsage {
cpu_fraction: f64,
}
-fn cpu_usage_calculation(prev_idle: &mut f64, prev_non_idle: &mut f64) -> error::Result<CpuUsage> {
+fn cpu_usage_calculation(
+ prev_idle: &mut f64, prev_non_idle: &mut f64,
+) -> error::CollectionResult<CpuUsage> {
let (idle, non_idle) = {
// From SO answer: https://stackoverflow.com/a/23376195
let first_line = {
@@ -299,7 +301,7 @@ pub(crate) struct ReadProcArgs {
pub(crate) fn linux_process_data(
collector: &mut DataCollector, time_difference_in_secs: u64,
-) -> error::Result<Vec<ProcessHarvest>> {
+) -> error::CollectionResult<Vec<ProcessHarvest>> {
let total_memory = collector.total_memory();
let prev_proc = PrevProc {
prev_idle: &mut collector.prev_idle,
@@ -402,8 +404,9 @@ pub(crate) fn linux_process_data(
Ok(process_vector)
} else {
- Err(BottomError::GenericError(
- "Could not calculate CPU usage.".to_string(),
+ Err(CollectionError::other(
+ "Process",
+ "Could not calculate CPU usage.",
))
}
}
diff --git a/src/data_collection/processes/unix/user_table.rs b/src/data_collection/processes/unix/user_table.rs
index 6245a858..5d5b2f04 100644
--- a/src/data_collection/processes/unix/user_table.rs
+++ b/src/data_collection/processes/unix/user_table.rs
@@ -1,6 +1,6 @@
use hashbrown::HashMap;
-use crate::utils::error;
+use crate::utils::error::{CollectionError, CollectionResult};
#[derive(Debug, Default)]
pub struct UserTable {
@@ -8,7 +8,7 @@ pub struct UserTable {
}
impl UserTable {
- pub fn get_uid_to_username_mapping(&mut self, uid: libc::uid_t) -> error::Result<String> {
+ pub fn get_uid_to_username_mapping(&mut self, uid: libc::uid_t) -> CollectionResult<String> {
if let Some(user) = self.uid_user_mapping.get(&uid) {
Ok(user.clone())
} else {
@@ -16,7 +16,7 @@ impl UserTable {
let passwd = unsafe { libc::getpwuid(uid) };
if passwd.is_null() {
- Err(error::BottomError::QueryError("Missing passwd".into()))
+ Err(CollectionError::other("processes", "Missing passwd"))
} else {
// SAFETY: We return early if passwd is null.
let username = unsafe { std::ffi::CStr::from_ptr((*passwd).pw_name) }
diff --git a/src/data_collection/temperature/linux.rs b/src/data_collection/temperature/linux.rs
index 50b858d1..1c1fb54e 100644
--- a/src/data_collection/temperature/linux.rs
+++ b/src/data_collection/temperature/linux.rs
@@ -9,7 +9,7 @@ use anyhow::Result;
use hashbrown::{HashMap, HashSet};
use super::{is_temp_filtered, TempHarvest, TemperatureType};
-use crate::{app::filter::Filter, utils::error::BottomError};
+use crate::{app::filter::Filter, utils::error::CollectionResult};
const EMPTY_NAME: &str = "Unknown";
@@ -20,12 +20,8 @@ struct HwmonResults {
}
/// Parses and reads temperatures that were in millidegree Celsius, and if successful, returns a temperature in Celsius.
-fn parse_temp(path: &Path) -> Result<f32> {
- Ok(fs::read_to_string(path)?
- .trim_end()
- .parse::<f32>()
- .map_err(|e| BottomError::ConversionError(e.to_string()))?
- / 1_000.0)
+fn parse_temp(path: &Path) -> CollectionResult<f32> {
+ Ok(fs::read_to_string(path)?.trim_end().parse::<f32>()? / 1_000.0)
}
/// Get all candidates from hwmon and coretemp. It will also return the number of entries from hwmon.
diff --git a/src/lib.rs b/src/lib.rs
index f80317e1..948aaeae 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -62,7 +62,7 @@ use crossterm::{
use data_conversion::*;
pub use options::args;
use options::ConfigV1;
-use utils::error;
+use utils::error::{self, ConfigResult};
#[allow(unused_imports)]
pub use utils::logging::*;
@@ -235,7 +235,7 @@ pub fn get_config_path(override_config_path: Option<&Path>) -> Option<PathBuf> {
}
}
-pub fn get_or_create_config(override_config_path: Option<&Path>) -> error::Result<ConfigV1> {
+pub fn get_or_create_config(override_config_path: Option<&Path>) -> ConfigResult<ConfigV1> {
let config_path = get_config_path(override_config_path);
if let Some(path) = &config_path {
@@ -258,7 +258,7 @@ pub fn get_or_create_config(override_config_path: Option<&Path>) -> error::Resul
pub fn try_drawing(
terminal: &mut tui::terminal::Terminal<tui::backend::CrosstermBackend<std::io::Stdout>>,
app: &mut App, painter: &mut canvas::Painter,
-) -> error::Result<()> {
+) -> error::DrawResult<()> {
if let Err(err) = painter.draw_data(terminal, app) {
cleanup_terminal(terminal)?;
Err(err)
@@ -269,7 +269,7 @@ pub fn try_drawing(
pub fn cleanup_terminal(
terminal: &mut tui::terminal::Terminal<tui::backend::CrosstermBackend<std::io::Stdout>>,
-) -> error::Result<()> {
+) -> error::DrawResult<()> {
disable_raw_mode()?;
execute!(
terminal.backend_mut(),
diff --git a/src/options.rs b/src/options.rs
index c98618b2..54cb9f12 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -32,7 +32,7 @@ use crate::{
data_collection::temperature::TemperatureType,
utils::{
data_units::DataUnit,
- error::{self, BottomError},
+ error::{self, BottomError, ConfigError, ConfigResult},
},
widgets::*,
};
@@ -369,7 +369,7 @@ pub fn init_app(
pub fn get_widget_layout(
args: &BottomArgs, config: &ConfigV1,
-) -> error::Result<(BottomLayout, u64, Option<BottomWidgetType>)> {
+) -> ConfigResult<(BottomLayout, u64, Option<BottomWidgetType>)> {
let cpu_left_legend = is_flag_enabled!(cpu_left_legend, args.cpu, config);
let (default_widget_type, mut default_widget_count) =
@@ -413,7 +413,7 @@ pub fn get_widget_layout(
cpu_left_legend,
)
})
- .collect::<error::Result<Vec<_>>>()?,
+ .collect::<ConfigResult<Vec<_>>>()?,
total_row_height_ratio: total_height_ratio,
};
@@ -422,8 +422,8 @@ pub fn get_widget_layout(
ret_bottom_layout.get_movement_mappings();
ret_bottom_layout
} else {
- return Err(BottomError::ConfigError(
- "please have at least one widget under the '[[row]]' section.".to_string(),
+ return Err(ConfigError::other(
+ "please have at least one widget under the '[[row]]' section.",
));
}
};
@@ -433,15 +433,13 @@ pub fn get_widget_layout(
fn get_update_rate(args: &BottomArgs, config: &ConfigV1) -> error::Result<u64> {
let update_rate = if let Some(update_rate) = &args.general.rate {
- try_parse_ms(update_rate).map_err(|_| {
- BottomError::ArgumentError("set your update rate to be valid".to_string())
- })?
+ try_parse_ms(update_rate)
+ .map_err(|_| BottomError::config("set your update rate to be valid"))?
} else if let Some(flags) = &config.flags {
if let Some(rate) = &flags.rate {
match rate {
- StringOrNum::String(s) => try_parse_ms(s).map_err(|_| {
- BottomError::ConfigError("set your update rate to be valid".to_string())
- })?,
+ StringOrNum::String(s) => try_parse_ms(s)
+ .map_err(|_| BottomError::config("set your update rate to be valid"))?,
StringOrNum::Num(n) => *n,
}
} else {
@@ -452,8 +450,8 @@ fn get_update_rate(args: &BottomArgs, config: &ConfigV1) -> error::Result<u64> {
};
if update_rate < 250 {
- return Err(BottomError::ConfigError(
- "set your update rate to be at least 250 ms.".to_string(),
+ return Err(BottomError::config(
+ "set your update rate to be at least 250 ms.",
));
}
@@ -469,7 +467,7 @@ fn get_temperature(args: &BottomArgs, config: &ConfigV1) -> error::Result<Temper
return Ok(TemperatureType::Celsius);
} else if let Some(flags) = &config.flags {
if let Some(temp_type) = &flags.temperature_type {
- return TemperatureType::from_str(temp_type).map_err(BottomError::ConfigError);
+ return TemperatureType::from_str(temp_type).map_err(BottomError::config);
}
}
Ok(TemperatureType::Celsius)
@@ -494,8 +492,8 @@ fn try_parse_ms(s: &str) -> error::Result<u64> {
} else if let Ok(val) = s.parse::<u64>() {
Ok(val)
} else {
- Err(BottomError::ConfigError(
- "could not parse as a valid 64-bit unsigned integer or a human time".to_string(),
+ Err(BottomError::config(
+ "could not parse as a valid 64-bit unsigned integer or a human time",
))
}
}
@@ -504,15 +502,13 @@ fn get_default_time_value(
args: &BottomArgs, config: &ConfigV1, retention_ms: u64,
) -> error::Result<u64> {
let default_time = if let Some(default_time_value) = &args.general.default_time_value {
- try_parse_ms(default_time_value).map_err(|_| {
- BottomError::ArgumentError("set your default time to be valid".to_string())
- })?
+ try_parse_ms(default_time_value)
+ .map_err(|_| BottomError::config("set your default time to be valid"))?
} else if let Some(flags) = &config.flags {
if let Some(default_time_value) = &flags.default_time_value {
match default_time_value {
- StringOrNum::String(s) => try_parse_ms(s).map_err(|_| {
- BottomError::ConfigError("set your default time to be valid".to_string())
- })?,
+ StringOrNum::String(s) => try_parse_ms(s)
+ .map_err(|_| BottomError::config("set your default time to be valid"))?,
StringOrNum::Num(n) => *n,
}
} else {
@@ -523,11 +519,11 @@ fn get_default_time_value(
};
if default_time < 30000 {
- return Err(BottomError::ConfigError(
- "set your default time to be at least 30s.".to_string(),
+ return Err(BottomError::config(
+ "set your default time to be at least 30s.",
));
} else if default_time > retention_ms {
- return Err(BottomError::ConfigError(format!(
+ return Err(BottomError::config(format!(
"set your default time to be at most {}.",
humantime::Duration::from(Duration::from_millis(retention_ms))
)));
@@ -540,15 +536,13 @@ fn get_time_interval(
args: &BottomArgs, config: &ConfigV1, retention_ms: u64,
) -> error::Result<u64> {
let time_interval = if let Some(time_interval) = &args.general.time_delta {
- try_parse_ms(time_interval).map_err(|_| {
- BottomError::ArgumentError("set your time delta to be valid".to_string())
- })?
+ try_parse_ms(time_interval)
+ .map_err(|_| BottomError::config("set your time delta to be valid"))?
} else if let Some(flags) = &config.flags {
if let Some(time_interval) = &flags.time_delta {
match time_interval {
- StringOrNum::String(s) => try_parse_ms(s).map_err(|_| {
- BottomError::ArgumentError("set your time delta to be valid".to_string())
- })?,
+ StringOrNum::String(s) => try_parse_ms(s)
+ .map_err(|_| BottomError::config("set your time delta to be valid"))?,
StringOrNum::Num(n) => *n,
}
} else {
@@ -559,22 +553,22 @@ fn get_time_interval(
};
if time_interval < 1000 {
- return Err(BottomError::ConfigError(
- "set your time delta to be at least 1s.".to_string(),
- ));
+ Err(BottomError::config(
+ "set your time delta to be at least 1s.",
+ ))
} else if time_interval > retention_ms {
- return Err(BottomError::ConfigError(format!(
+ Err(BottomE