cargo_fixit/
errors.rs

1/// Common result type
2pub type CargoResult<T> = anyhow::Result<T>;
3
4/// Common error type
5pub type Error = anyhow::Error;
6
7pub use anyhow::Context;
8
9/// CLI-specific result
10pub type CliResult = Result<(), CliError>;
11
12#[derive(Debug)]
13/// The CLI error is the error type used at Cargo's CLI-layer.
14///
15/// All errors from the lib side of Cargo will get wrapped with this error.
16/// Other errors (such as command-line argument validation) will create this
17/// directly.
18pub struct CliError {
19    /// The error to display. This can be `None` in rare cases to exit with a
20    /// code without displaying a message. For example `cargo run -q` where
21    /// the resulting process exits with a nonzero code (on Windows), or an
22    /// external subcommand that exits nonzero (we assume it printed its own
23    /// message).
24    pub error: Option<anyhow::Error>,
25    /// The process exit code.
26    pub exit_code: i32,
27}
28
29impl CliError {
30    /// Attach an error code to an error
31    pub fn new(error: anyhow::Error, code: i32) -> CliError {
32        CliError {
33            error: Some(error),
34            exit_code: code,
35        }
36    }
37
38    /// Silent error
39    pub fn code(code: i32) -> CliError {
40        CliError {
41            error: None,
42            exit_code: code,
43        }
44    }
45}
46
47impl From<anyhow::Error> for CliError {
48    fn from(err: anyhow::Error) -> CliError {
49        CliError::new(err, 101)
50    }
51}
52
53impl From<clap::Error> for CliError {
54    fn from(err: clap::Error) -> CliError {
55        #[allow(clippy::bool_to_int_with_if)]
56        let code = if err.use_stderr() { 1 } else { 0 };
57        CliError::new(err.into(), code)
58    }
59}
60
61impl From<std::io::Error> for CliError {
62    fn from(err: std::io::Error) -> CliError {
63        CliError::new(err.into(), 1)
64    }
65}