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 } |