diff --git a/src/authors/csv/reader.rs b/src/authors/csv/reader.rs index 9afdea7..b575f7e 100644 --- a/src/authors/csv/reader.rs +++ b/src/authors/csv/reader.rs @@ -2,6 +2,7 @@ use super::super::author::{Author, AuthorsProvider}; use super::mapper; use crate::authors::err::AuthorsError; use crate::common::conf; +use crate::common::err::SystemError; use crate::common::fs::file_reader::{Lines, Reader}; use crate::cositas::CustomResult; use std::env; @@ -34,7 +35,7 @@ impl CSVReader { fn from_cwd_fallback_home(file_reader: &dyn Reader) -> CustomResult { let file_path = &conf::authors_file(); let dir_path = &conf::authors_dir(); - let cwd = env::current_dir()?; + let cwd = env::current_dir().map_err(|_| SystemError::EnvVar("CWD".to_string()))?; file_reader .read_non_empty_lines(&cwd.join(file_path)) diff --git a/src/common/err.rs b/src/common/err.rs index 4a00baf..bb79ee0 100644 --- a/src/common/err.rs +++ b/src/common/err.rs @@ -3,8 +3,11 @@ use std::{any::Any, error::Error, fmt::Display}; #[derive(Debug)] pub enum SystemError { - Runner(String), + Runner(String, String), Unknown(String), + Read(String), + Write(String), + EnvVar(String), } impl Error for SystemError {} @@ -17,10 +20,13 @@ impl CustomError for SystemError { impl PartialEq for SystemError { fn eq(&self, other: &Self) -> bool { - matches!((self, other), |(SystemError::Runner(_), SystemError::Runner(_))| ( - SystemError::Unknown(_), - SystemError::Unknown(_) - )) + matches!((self, other), |( + SystemError::Runner(_, _), + SystemError::Runner(_, _), + )| (SystemError::Unknown(_), SystemError::Unknown(_)) + | (SystemError::Read(_), SystemError::Read(_)) + | (SystemError::Write(_), SystemError::Write(_)) + | (SystemError::EnvVar(_), SystemError::EnvVar(_))) } } @@ -28,8 +34,11 @@ impl Display for SystemError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "System failure: ")?; match self { - SystemError::Runner(err) => write!(f, "Command failed with: {err}"), + SystemError::Runner(cmd, err) => write!(f, "Command {cmd} failed with: {err}"), SystemError::Unknown(err) => write!(f, "{err}"), + SystemError::Read(err) => write!(f, "Could not read {err}"), + SystemError::Write(err) => write!(f, "Could not write {err}"), + SystemError::EnvVar(var) => write!(f, "Could not get {var} from env var"), } } } @@ -41,12 +50,24 @@ mod tests { #[test] fn test_system_error_display() { assert_eq!( - format!("{}", SystemError::Runner("error".to_string())), - "System failure: Command failed with: error" + format!("{}", SystemError::Runner("cmd".to_string(), "error".to_string())), + "System failure: Command cmd failed with: error" ); assert_eq!( format!("{}", SystemError::Unknown("oops".to_string())), "System failure: oops" ); + assert_eq!( + format!("{}", SystemError::Read("file".to_string())), + "System failure: Could not read file" + ); + assert_eq!( + format!("{}", SystemError::Write("file".to_string())), + "System failure: Could not write file" + ); + assert_eq!( + format!("{}", SystemError::EnvVar("var".to_string())), + "System failure: Could not get var from env var" + ); } } diff --git a/src/common/fs/file_reader.rs b/src/common/fs/file_reader.rs index a25f92a..274672c 100644 --- a/src/common/fs/file_reader.rs +++ b/src/common/fs/file_reader.rs @@ -1,4 +1,4 @@ -use crate::cositas::CustomResult; +use crate::{common::err::SystemError, cositas::CustomResult}; use std::{ fs::File, io::{BufRead, BufReader}, @@ -22,10 +22,12 @@ impl SimpleReader { impl Reader for SimpleReader { fn read_non_empty_lines(&self, path: &Path) -> CustomResult { - Ok(BufReader::new(File::open(path)?) - .lines() - .map_while(core::result::Result::ok) - .filter(|line| !line.trim().is_empty()) - .collect()) + Ok( + BufReader::new(File::open(path).map_err(|e| SystemError::Read(e.to_string()))?) + .lines() + .map_while(core::result::Result::ok) + .filter(|line| !line.trim().is_empty()) + .collect(), + ) } } diff --git a/src/common/fs/file_writer.rs b/src/common/fs/file_writer.rs index 638f87f..023f6ee 100644 --- a/src/common/fs/file_writer.rs +++ b/src/common/fs/file_writer.rs @@ -2,6 +2,7 @@ use std::fs::{File, OpenOptions}; use std::io::Write; use std::path::Path; +use crate::common::err::SystemError; use crate::cositas::CustomResult; #[cfg_attr(test, mockall::automock)] @@ -18,19 +19,29 @@ impl SimpleWriter { } fn write(mut file: File, content: &str) -> CustomResult<()> { - file.write_all(content.as_bytes())?; - file.flush().map_err(Into::into) + file.write_all(content.as_bytes()) + .map_err(|e| SystemError::Write(e.to_string()))?; + Ok(file.flush().map_err(|e| SystemError::Write(e.to_string()))?) } } impl Writer for SimpleWriter { fn overwrite(&self, path: &Path, content: &str) -> CustomResult<()> { - let file = OpenOptions::new().write(true).truncate(true).create(true).open(path)?; + let file = OpenOptions::new() + .write(true) + .truncate(true) + .create(true) + .open(path) + .map_err(|e| SystemError::Write(e.to_string()))?; Self::write(file, content) } fn append(&self, path: &Path, content: &str) -> CustomResult<()> { - let file = OpenOptions::new().write(true).append(true).open(path)?; + let file = OpenOptions::new() + .write(true) + .append(true) + .open(path) + .map_err(|e| SystemError::Write(e.to_string()))?; Self::write(file, content) } } diff --git a/src/common/runner.rs b/src/common/runner.rs index be431c9..f941fb5 100644 --- a/src/common/runner.rs +++ b/src/common/runner.rs @@ -20,15 +20,23 @@ impl CommandRunner { impl Runner for CommandRunner { fn spawn(&self, cmd: &str, arg: &str) -> CustomResult<()> { - Ok(Command::new(cmd).arg(arg).spawn().map(|_| ())?) + Ok(Command::new(cmd) + .arg(arg) + .spawn() + .map(|_| ()) + .map_err(|e| SystemError::Runner(cmd.to_string(), e.to_string()))?) } fn run(&self, cmd: &str, arg: &str) -> CustomResult<()> { - Command::new(cmd) + if Command::new(cmd) .arg(arg) - .status()? + .status() + .map_err(|e| SystemError::Runner(cmd.to_string(), e.to_string()))? .success() - .then_some(()) - .ok_or(SystemError::Runner("Command failed".to_string()).into()) + { + Ok(()) + } else { + Err(SystemError::Runner(cmd.to_string(), "exit code 1".to_string()).into()) + } } } diff --git a/src/cositas.rs b/src/cositas.rs index 7b7e86b..1df955a 100644 --- a/src/cositas.rs +++ b/src/cositas.rs @@ -36,15 +36,9 @@ impl From for Box { } } -impl From for Box { - fn from(e: std::io::Error) -> Box { - Box::new(SystemError::Unknown(e.to_string())) - } -} - impl From for Box { fn from(e: std::env::VarError) -> Box { - Box::new(SystemError::Unknown(e.to_string())) + Box::new(SystemError::EnvVar(e.to_string())) } }