error.rs
124 lines
| 4.0 KiB
| application/rls-services+xml
|
RustLexer
Antoine Cezar
|
r45592 | use crate::exitcode; | ||
use crate::ui::UiError; | ||||
Raphaël Gomès
|
r46598 | use format_bytes::format_bytes; | ||
Antoine Cezar
|
r45922 | use hg::operations::{FindRootError, FindRootErrorKind}; | ||
Simon Sapin
|
r46536 | use hg::requirements::RequirementsError; | ||
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), | ||
Simon Sapin
|
r46536 | /// `.hg/requires` | ||
RequirementsError(RequirementsError), | ||||
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
|
r46113 | /// A mercurial capability as not been implemented. | ||
Unimplemented, | ||||
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, | ||||
Simon Sapin
|
r46549 | CommandErrorKind::RequirementsError( | ||
RequirementsError::Unsupported { .. }, | ||||
) => exitcode::UNIMPLEMENTED_COMMAND, | ||||
Simon Sapin
|
r46536 | CommandErrorKind::RequirementsError(_) => exitcode::ABORT, | ||
Antoine Cezar
|
r45592 | CommandErrorKind::StdoutError => exitcode::ABORT, | ||
CommandErrorKind::StderrError => exitcode::ABORT, | ||||
Antoine Cezar
|
r45923 | CommandErrorKind::Abort(_) => exitcode::ABORT, | ||
Antoine Cezar
|
r46113 | CommandErrorKind::Unimplemented => exitcode::UNIMPLEMENTED_COMMAND, | ||
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 { | ||||
CommandErrorKind::RootNotFound(path) => { | ||||
let bytes = get_bytes_from_path(path); | ||||
Raphaël Gomès
|
r46598 | Some(format_bytes!( | ||
b"abort: no repository found in '{}' (.hg not found)!\n", | ||||
bytes.as_slice() | ||||
)) | ||||
Antoine Cezar
|
r45920 | } | ||
Raphaël Gomès
|
r46598 | CommandErrorKind::CurrentDirNotFound(e) => Some(format_bytes!( | ||
b"abort: error getting current working directory: {}\n", | ||||
e.to_string().as_bytes(), | ||||
)), | ||||
Simon Sapin
|
r46536 | CommandErrorKind::RequirementsError( | ||
RequirementsError::Corrupted, | ||||
) => Some( | ||||
"abort: .hg/requires is corrupted\n".as_bytes().to_owned(), | ||||
), | ||||
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. | ||||
Antoine Cezar
|
r46010 | pub fn exit(&self) { | ||
Antoine Cezar
|
r45592 | 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), | ||||
}, | ||||
} | ||||
} | ||||
} | ||||
Simon Sapin
|
r46536 | |||
impl From<RequirementsError> for CommandError { | ||||
fn from(err: RequirementsError) -> Self { | ||||
CommandError { | ||||
kind: CommandErrorKind::RequirementsError(err), | ||||
} | ||||
} | ||||
} | ||||