error.rs
110 lines
| 3.4 KiB
| application/rls-services+xml
|
RustLexer
Antoine Cezar
|
r45592 | use crate::exitcode; | ||
use crate::ui::UiError; | ||||
Antoine Cezar
|
r45922 | use hg::operations::{FindRootError, FindRootErrorKind}; | ||
Antoine Cezar
|
r45920 | use hg::utils::files::get_bytes_from_path; | ||
Antoine Cezar
|
r45592 | use std::convert::From; | ||
Antoine Cezar
|
r45920 | use std::path::PathBuf; | ||
Antoine Cezar
|
r45592 | |||
/// The kind of command error | ||||
Antoine Cezar
|
r45920 | #[derive(Debug)] | ||
Antoine Cezar
|
r45592 | pub enum CommandErrorKind { | ||
/// The root of the repository cannot be found | ||||
Antoine Cezar
|
r45920 | RootNotFound(PathBuf), | ||
Antoine Cezar
|
r45592 | /// The current directory cannot be found | ||
Antoine Cezar
|
r45920 | CurrentDirNotFound(std::io::Error), | ||
Antoine Cezar
|
r45592 | /// The standard output stream cannot be written to | ||
StdoutError, | ||||
/// The standard error stream cannot be written to | ||||
StderrError, | ||||
Antoine Cezar
|
r45923 | /// The command aborted | ||
Abort(Option<Vec<u8>>), | ||||
Antoine Cezar
|
r45592 | } | ||
impl CommandErrorKind { | ||||
pub fn get_exit_code(&self) -> exitcode::ExitCode { | ||||
match self { | ||||
Antoine Cezar
|
r45920 | CommandErrorKind::RootNotFound(_) => exitcode::ABORT, | ||
CommandErrorKind::CurrentDirNotFound(_) => exitcode::ABORT, | ||||
Antoine Cezar
|
r45592 | CommandErrorKind::StdoutError => exitcode::ABORT, | ||
CommandErrorKind::StderrError => exitcode::ABORT, | ||||
Antoine Cezar
|
r45923 | CommandErrorKind::Abort(_) => exitcode::ABORT, | ||
Antoine Cezar
|
r45592 | } | ||
} | ||||
Antoine Cezar
|
r45920 | |||
/// Return the message corresponding to the error kind if any | ||||
pub fn get_error_message_bytes(&self) -> Option<Vec<u8>> { | ||||
match self { | ||||
// TODO use formating macro | ||||
CommandErrorKind::RootNotFound(path) => { | ||||
let bytes = get_bytes_from_path(path); | ||||
Some( | ||||
[ | ||||
b"abort: no repository found in '", | ||||
bytes.as_slice(), | ||||
b"' (.hg not found)!\n", | ||||
] | ||||
.concat(), | ||||
) | ||||
} | ||||
// TODO use formating macro | ||||
CommandErrorKind::CurrentDirNotFound(e) => Some( | ||||
[ | ||||
b"abort: error getting current working directory: ", | ||||
e.to_string().as_bytes(), | ||||
b"\n", | ||||
] | ||||
.concat(), | ||||
), | ||||
Antoine Cezar
|
r45923 | CommandErrorKind::Abort(message) => message.to_owned(), | ||
Antoine Cezar
|
r45920 | _ => None, | ||
} | ||||
} | ||||
Antoine Cezar
|
r45592 | } | ||
Antoine Cezar
|
r45515 | /// The error type for the Command trait | ||
Antoine Cezar
|
r45920 | #[derive(Debug)] | ||
Antoine Cezar
|
r45592 | pub struct CommandError { | ||
pub kind: CommandErrorKind, | ||||
} | ||||
impl CommandError { | ||||
/// Exist the process with the corresponding exit code. | ||||
pub fn exit(&self) -> () { | ||||
std::process::exit(self.kind.get_exit_code()) | ||||
} | ||||
Antoine Cezar
|
r45920 | |||
/// Return the message corresponding to the command error if any | ||||
pub fn get_error_message_bytes(&self) -> Option<Vec<u8>> { | ||||
self.kind.get_error_message_bytes() | ||||
} | ||||
Antoine Cezar
|
r45592 | } | ||
impl From<CommandErrorKind> for CommandError { | ||||
fn from(kind: CommandErrorKind) -> Self { | ||||
CommandError { kind } | ||||
} | ||||
} | ||||
impl From<UiError> for CommandError { | ||||
fn from(error: UiError) -> Self { | ||||
CommandError { | ||||
kind: match error { | ||||
UiError::StdoutError(_) => CommandErrorKind::StdoutError, | ||||
UiError::StderrError(_) => CommandErrorKind::StderrError, | ||||
}, | ||||
} | ||||
} | ||||
} | ||||
Antoine Cezar
|
r45922 | |||
impl From<FindRootError> for CommandError { | ||||
fn from(err: FindRootError) -> Self { | ||||
match err.kind { | ||||
FindRootErrorKind::RootNotFound(path) => CommandError { | ||||
kind: CommandErrorKind::RootNotFound(path), | ||||
}, | ||||
FindRootErrorKind::GetCurrentDirError(e) => CommandError { | ||||
kind: CommandErrorKind::CurrentDirNotFound(e), | ||||
}, | ||||
} | ||||
} | ||||
} | ||||