summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTim Oram <dev@mitmaro.ca>2020-09-21 09:43:04 -0230
committerTim Oram <dev@mitmaro.ca>2020-09-21 09:54:10 -0230
commit6ec8d78c48c8e8dd82812415108e2252fd652b24 (patch)
tree18ddd8e53339f200e5dbf4b62e1dbd2b7b3fcce7 /src
parent7db93e38fb3e4d481139595857c15d656a8e5a55 (diff)
Use anyhow in the main application struct
The main application struct uses String errors, which make it difficult to provide context on errors. This updates the struct to provide errors with anyhow and fixes any references that used to depend on the String errors. While working on the code, several poor usages of match have been replaced with `map_or*`, `unwrap_or*` chains.
Diffstat (limited to 'src')
-rw-r--r--src/external_editor/mod.rs6
-rw-r--r--src/git_interactive.rs39
-rw-r--r--src/main.rs14
-rw-r--r--src/process/mod.rs11
4 files changed, 26 insertions, 44 deletions
diff --git a/src/external_editor/mod.rs b/src/external_editor/mod.rs
index ef4f476..fc25135 100644
--- a/src/external_editor/mod.rs
+++ b/src/external_editor/mod.rs
@@ -57,7 +57,7 @@ impl<'e> ProcessModule for ExternalEditor<'e> {
result = result.error(e.as_str()).exit_status(ExitStatus::StateError);
}
else if let Err(e) = git_interactive.reload_file() {
- result = result.error(e.as_str()).exit_status(ExitStatus::StateError);
+ result = result.error(e.to_string().as_str()).exit_status(ExitStatus::StateError);
}
else if git_interactive.get_lines().is_empty() {
self.state = ExternalEditorState::Empty;
@@ -115,7 +115,7 @@ impl<'e> ExternalEditor<'e> {
}
})?;
- git_interactive.write_file()?;
+ git_interactive.write_file().map_err(|err| err.to_string())?;
let filepath = git_interactive.get_filepath();
let callback = || -> Result<ProcessExitStatus, String> {
let mut file_pattern_found = false;
@@ -279,7 +279,7 @@ mod tests {
|module: &mut dyn ProcessModule, git_interactive: &mut GitInteractive| {
assert_process_result!(
module.process(git_interactive),
- error = "Error reading file, Invalid line: this-is-invalid",
+ error = "Invalid line: this-is-invalid",
exit_status = ExitStatus::StateError
);
}
diff --git a/src/git_interactive.rs b/src/git_interactive.rs
index 26e9aea..b52c9e9 100644
--- a/src/git_interactive.rs
+++ b/src/git_interactive.rs
@@ -1,20 +1,21 @@
use crate::list::action::Action;
use crate::list::line::Line;
+use anyhow::{anyhow, Result};
use std::cmp;
use std::fs::{read_to_string, File};
use std::io::Write;
use std::path::PathBuf;
-fn load_filepath(path: &PathBuf, comment_char: &str) -> Result<Vec<Line>, String> {
+fn load_filepath(path: &PathBuf, comment_char: &str) -> Result<Vec<Line>> {
read_to_string(&path)
- .map_err(|why| format!("Error reading file, {}\nReason: {}", path.display(), why))?
+ .map_err(|err| anyhow!("Error reading file: {}", path.display()).context(err))?
.lines()
.filter_map(|l| {
if l.starts_with(comment_char) || l.is_empty() {
None
}
else {
- Some(Line::new(l).map_err(|e| format!("Error reading file, {}", e)))
+ Some(Line::new(l).map_err(|err| anyhow!("Error reading file: {}", path.display()).context(err)))
}
})
.collect()
@@ -29,7 +30,7 @@ pub struct GitInteractive {
}
impl GitInteractive {
- pub(crate) fn new(lines: Vec<Line>, path: PathBuf, comment_char: &str) -> Result<Self, String> {
+ pub(crate) fn new(lines: Vec<Line>, path: PathBuf, comment_char: &str) -> Result<Self> {
Ok(Self {
filepath: path,
lines,
@@ -39,38 +40,24 @@ impl GitInteractive {
})
}
- pub(crate) fn new_from_filepath(filepath: &str, comment_char: &str) -> Result<Self, String> {
+ pub(crate) fn new_from_filepath(filepath: &str, comment_char: &str) -> Result<Self> {
let path = PathBuf::from(filepath);
let lines = load_filepath(&path, comment_char)?;
Self::new(lines, path, comment_char)
}
- pub(crate) fn write_file(&self) -> Result<(), String> {
- let mut file = match File::create(&self.filepath) {
- Ok(file) => file,
- Err(why) => {
- return Err(format!(
- "Error opening file, {}\nReason: {}",
- self.filepath.display(),
- why
- ));
- },
- };
+ pub(crate) fn write_file(&self) -> Result<()> {
+ let mut file = File::create(&self.filepath)
+ .map_err(|err| anyhow!("Error opening file: {}", self.filepath.display()).context(err))?;
for line in &self.lines {
- match writeln!(file, "{}", line.to_text()) {
- Ok(_) => {},
- Err(why) => {
- return Err(format!("Error writing to file, {}", why));
- },
- }
+ writeln!(file, "{}", line.to_text())
+ .map_err(|err| anyhow!("Error writing file: {}", self.filepath.display()).context(err))?;
}
Ok(())
}
- pub(crate) fn reload_file(&mut self) -> Result<(), String> {
- let lines = load_filepath(&self.filepath, self.comment_char.as_str())?;
-
- self.lines = lines;
+ pub(crate) fn reload_file(&mut self) -> Result<()> {
+ self.lines = load_filepath(&self.filepath, self.comment_char.as_str())?;
Ok(())
}
diff --git a/src/main.rs b/src/main.rs
index f5f1cd8..2fb6c73 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -84,15 +84,13 @@ fn try_main() -> Result<ExitStatus, Exit> {
}
})?;
- let git_interactive = match GitInteractive::new_from_filepath(filepath, config.git.comment_char.as_str()) {
- Ok(gi) => gi,
- Err(message) => {
- return Err(Exit {
- message,
+ let git_interactive =
+ GitInteractive::new_from_filepath(filepath, config.git.comment_char.as_str()).map_err(|err| {
+ Exit {
+ message: err.to_string(),
status: ExitStatus::FileReadError,
- });
- },
- };
+ }
+ })?;
if git_interactive.is_noop() {
return Err(Exit {
diff --git a/src/process/mod.rs b/src/process/mod.rs
index 15ccc0f..fff6794 100644
--- a/src/process/mod.rs
+++ b/src/process/mod.rs
@@ -118,13 +118,10 @@ impl<'r> Process<'r> {
}
fn exit_end(&mut self) -> Result<(), String> {
- match self.git_interactive.write_file() {
- Ok(_) => {},
- Err(msg) => {
- self.exit_status = Some(ExitStatus::FileWriteError);
- return Err(msg);
- },
- }
+ self.git_interactive.write_file().map_err(|err| {
+ self.exit_status = Some(ExitStatus::FileWriteError);
+ err.to_string()
+ })?;
Ok(())
}
}