improve errors management

This commit is contained in:
Clément DOUIN
2021-03-12 22:59:08 +01:00
parent 781c4a2722
commit 1e5cce0205
10 changed files with 699 additions and 894 deletions
+19 -47
View File
@@ -1,72 +1,43 @@
use error_chain::error_chain;
use std::{
env, fmt,
env,
fs::{remove_file, File},
io::{self, Read, Write},
process::Command,
result,
};
// Error wrapper
#[derive(Debug)]
pub enum Error {
IoError(io::Error),
GetEditorEnvVarNotFoundError(env::VarError),
AskForConfirmationDeniedError,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "input: ")?;
match self {
Error::IoError(err) => err.fmt(f),
Error::GetEditorEnvVarNotFoundError(err) => err.fmt(f),
Error::AskForConfirmationDeniedError => write!(f, "action cancelled"),
}
}
}
impl From<io::Error> for Error {
fn from(err: io::Error) -> Error {
Error::IoError(err)
}
}
impl From<env::VarError> for Error {
fn from(err: env::VarError) -> Error {
Error::GetEditorEnvVarNotFoundError(err)
}
}
// Result wrapper
type Result<T> = result::Result<T, Error>;
// Utils
error_chain! {}
pub fn open_editor_with_tpl(tpl: &[u8]) -> Result<String> {
// Creates draft file
let mut draft_path = env::temp_dir();
draft_path.push("himalaya-draft.mail");
File::create(&draft_path)?.write(tpl)?;
File::create(&draft_path)
.chain_err(|| format!("Cannot create file `{}`", draft_path.to_string_lossy()))?
.write(tpl)
.chain_err(|| format!("Cannot write file `{}`", draft_path.to_string_lossy()))?;
// Opens editor and saves user input to draft file
Command::new(env::var("EDITOR")?)
Command::new(env::var("EDITOR").chain_err(|| "Cannot find `EDITOR` env var")?)
.arg(&draft_path)
.status()?;
.status()
.chain_err(|| "Cannot start editor")?;
// Extracts draft file content
let mut draft = String::new();
File::open(&draft_path)?.read_to_string(&mut draft)?;
remove_file(&draft_path)?;
File::open(&draft_path)
.chain_err(|| format!("Cannot open file `{}`", draft_path.to_string_lossy()))?
.read_to_string(&mut draft)
.chain_err(|| format!("Cannot read file `{}`", draft_path.to_string_lossy()))?;
remove_file(&draft_path)
.chain_err(|| format!("Cannot remove file `{}`", draft_path.to_string_lossy()))?;
Ok(draft)
}
pub fn ask_for_confirmation(prompt: &str) -> Result<()> {
print!("{} (y/n) ", prompt);
io::stdout().flush()?;
io::stdout().flush().chain_err(|| "Cannot flush stdout")?;
match io::stdin()
.bytes()
@@ -75,6 +46,7 @@ pub fn ask_for_confirmation(prompt: &str) -> Result<()> {
.map(|bytes| bytes as char)
{
Some('y') | Some('Y') => Ok(()),
_ => Err(Error::AskForConfirmationDeniedError),
Some(choice) => Err(format!("Invalid choice `{}`", choice).into()),
None => Err("Empty choice".into()),
}
}