rust/rhg/src/error.rs
changeset 46434 3e2d539d0d1a
parent 45984 fada33872b5b
child 46435 2e2033081274
equal deleted inserted replaced
46433:4b381dbbf8b7 46434:3e2d539d0d1a
     1 use crate::exitcode;
     1 use crate::exitcode;
     2 use crate::ui::UiError;
     2 use crate::ui::UiError;
     3 use format_bytes::format_bytes;
     3 use format_bytes::format_bytes;
     4 use hg::operations::{FindRootError, FindRootErrorKind};
     4 use hg::operations::FindRootError;
     5 use hg::requirements::RequirementsError;
     5 use hg::requirements::RequirementsError;
     6 use hg::utils::files::get_bytes_from_path;
     6 use hg::utils::files::get_bytes_from_path;
     7 use std::convert::From;
     7 use std::convert::From;
     8 use std::path::PathBuf;
     8 use std::path::PathBuf;
     9 
     9 
    10 /// The kind of command error
    10 /// The kind of command error
    11 #[derive(Debug)]
    11 #[derive(Debug)]
    12 pub enum CommandErrorKind {
    12 pub enum CommandError {
    13     /// The root of the repository cannot be found
    13     /// The root of the repository cannot be found
    14     RootNotFound(PathBuf),
    14     RootNotFound(PathBuf),
    15     /// The current directory cannot be found
    15     /// The current directory cannot be found
    16     CurrentDirNotFound(std::io::Error),
    16     CurrentDirNotFound(std::io::Error),
    17     /// `.hg/requires`
    17     /// `.hg/requires`
    24     Abort(Option<Vec<u8>>),
    24     Abort(Option<Vec<u8>>),
    25     /// A mercurial capability as not been implemented.
    25     /// A mercurial capability as not been implemented.
    26     Unimplemented,
    26     Unimplemented,
    27 }
    27 }
    28 
    28 
    29 impl CommandErrorKind {
    29 impl CommandError {
    30     pub fn get_exit_code(&self) -> exitcode::ExitCode {
    30     pub fn get_exit_code(&self) -> exitcode::ExitCode {
    31         match self {
    31         match self {
    32             CommandErrorKind::RootNotFound(_) => exitcode::ABORT,
    32             CommandError::RootNotFound(_) => exitcode::ABORT,
    33             CommandErrorKind::CurrentDirNotFound(_) => exitcode::ABORT,
    33             CommandError::CurrentDirNotFound(_) => exitcode::ABORT,
    34             CommandErrorKind::RequirementsError(
    34             CommandError::RequirementsError(
    35                 RequirementsError::Unsupported { .. },
    35                 RequirementsError::Unsupported { .. },
    36             ) => exitcode::UNIMPLEMENTED_COMMAND,
    36             ) => exitcode::UNIMPLEMENTED_COMMAND,
    37             CommandErrorKind::RequirementsError(_) => exitcode::ABORT,
    37             CommandError::RequirementsError(_) => exitcode::ABORT,
    38             CommandErrorKind::StdoutError => exitcode::ABORT,
    38             CommandError::StdoutError => exitcode::ABORT,
    39             CommandErrorKind::StderrError => exitcode::ABORT,
    39             CommandError::StderrError => exitcode::ABORT,
    40             CommandErrorKind::Abort(_) => exitcode::ABORT,
    40             CommandError::Abort(_) => exitcode::ABORT,
    41             CommandErrorKind::Unimplemented => exitcode::UNIMPLEMENTED_COMMAND,
    41             CommandError::Unimplemented => exitcode::UNIMPLEMENTED_COMMAND,
    42         }
    42         }
    43     }
    43     }
    44 
    44 
    45     /// Return the message corresponding to the error kind if any
    45     /// Return the message corresponding to the error if any
    46     pub fn get_error_message_bytes(&self) -> Option<Vec<u8>> {
    46     pub fn get_error_message_bytes(&self) -> Option<Vec<u8>> {
    47         match self {
    47         match self {
    48             CommandErrorKind::RootNotFound(path) => {
    48             CommandError::RootNotFound(path) => {
    49                 let bytes = get_bytes_from_path(path);
    49                 let bytes = get_bytes_from_path(path);
    50                 Some(format_bytes!(
    50                 Some(format_bytes!(
    51                     b"abort: no repository found in '{}' (.hg not found)!\n",
    51                     b"abort: no repository found in '{}' (.hg not found)!\n",
    52                     bytes.as_slice()
    52                     bytes.as_slice()
    53                 ))
    53                 ))
    54             }
    54             }
    55             CommandErrorKind::CurrentDirNotFound(e) => Some(format_bytes!(
    55             CommandError::CurrentDirNotFound(e) => Some(format_bytes!(
    56                 b"abort: error getting current working directory: {}\n",
    56                 b"abort: error getting current working directory: {}\n",
    57                 e.to_string().as_bytes(),
    57                 e.to_string().as_bytes(),
    58             )),
    58             )),
    59             CommandErrorKind::RequirementsError(
    59             CommandError::RequirementsError(RequirementsError::Corrupted) => {
    60                 RequirementsError::Corrupted,
    60                 Some(
    61             ) => Some(
    61                     "abort: .hg/requires is corrupted\n".as_bytes().to_owned(),
    62                 "abort: .hg/requires is corrupted\n".as_bytes().to_owned(),
    62                 )
    63             ),
    63             }
    64             CommandErrorKind::Abort(message) => message.to_owned(),
    64             CommandError::Abort(message) => message.to_owned(),
    65             _ => None,
    65             _ => None,
    66         }
    66         }
    67     }
    67     }
    68 }
       
    69 
    68 
    70 /// The error type for the Command trait
       
    71 #[derive(Debug)]
       
    72 pub struct CommandError {
       
    73     pub kind: CommandErrorKind,
       
    74 }
       
    75 
       
    76 impl CommandError {
       
    77     /// Exist the process with the corresponding exit code.
    69     /// Exist the process with the corresponding exit code.
    78     pub fn exit(&self) {
    70     pub fn exit(&self) {
    79         std::process::exit(self.kind.get_exit_code())
    71         std::process::exit(self.get_exit_code())
    80     }
       
    81 
       
    82     /// Return the message corresponding to the command error if any
       
    83     pub fn get_error_message_bytes(&self) -> Option<Vec<u8>> {
       
    84         self.kind.get_error_message_bytes()
       
    85     }
       
    86 }
       
    87 
       
    88 impl From<CommandErrorKind> for CommandError {
       
    89     fn from(kind: CommandErrorKind) -> Self {
       
    90         CommandError { kind }
       
    91     }
    72     }
    92 }
    73 }
    93 
    74 
    94 impl From<UiError> for CommandError {
    75 impl From<UiError> for CommandError {
    95     fn from(error: UiError) -> Self {
    76     fn from(error: UiError) -> Self {
    96         CommandError {
    77         match error {
    97             kind: match error {
    78             UiError::StdoutError(_) => CommandError::StdoutError,
    98                 UiError::StdoutError(_) => CommandErrorKind::StdoutError,
    79             UiError::StderrError(_) => CommandError::StderrError,
    99                 UiError::StderrError(_) => CommandErrorKind::StderrError,
       
   100             },
       
   101         }
    80         }
   102     }
    81     }
   103 }
    82 }
   104 
    83 
   105 impl From<FindRootError> for CommandError {
    84 impl From<FindRootError> for CommandError {
   106     fn from(err: FindRootError) -> Self {
    85     fn from(err: FindRootError) -> Self {
   107         match err.kind {
    86         match err {
   108             FindRootErrorKind::RootNotFound(path) => CommandError {
    87             FindRootError::RootNotFound(path) => {
   109                 kind: CommandErrorKind::RootNotFound(path),
    88                 CommandError::RootNotFound(path)
   110             },
    89             }
   111             FindRootErrorKind::GetCurrentDirError(e) => CommandError {
    90             FindRootError::GetCurrentDirError(e) => {
   112                 kind: CommandErrorKind::CurrentDirNotFound(e),
    91                 CommandError::CurrentDirNotFound(e)
   113             },
    92             }
   114         }
    93         }
   115     }
    94     }
   116 }
    95 }
   117 
    96 
   118 impl From<RequirementsError> for CommandError {
    97 impl From<RequirementsError> for CommandError {
   119     fn from(err: RequirementsError) -> Self {
    98     fn from(err: RequirementsError) -> Self {
   120         CommandError {
    99         CommandError::RequirementsError(err)
   121             kind: CommandErrorKind::RequirementsError(err),
       
   122         }
       
   123     }
   100     }
   124 }
   101 }