cargo_edit_9/
errors.rs

1use std::fmt::Display;
2
3/// Common result type
4pub type CargoResult<T> = anyhow::Result<T>;
5
6/// Common error type
7pub type Error = anyhow::Error;
8
9pub use anyhow::Context;
10
11/// CLI-specific result
12pub type CliResult = Result<(), CliError>;
13
14#[derive(Debug)]
15/// The CLI error is the error type used at Cargo's CLI-layer.
16///
17/// All errors from the lib side of Cargo will get wrapped with this error.
18/// Other errors (such as command-line argument validation) will create this
19/// directly.
20pub struct CliError {
21    /// The error to display. This can be `None` in rare cases to exit with a
22    /// code without displaying a message. For example `cargo run -q` where
23    /// the resulting process exits with a nonzero code (on Windows), or an
24    /// external subcommand that exits nonzero (we assume it printed its own
25    /// message).
26    pub error: Option<anyhow::Error>,
27    /// The process exit code.
28    pub exit_code: i32,
29}
30
31impl CliError {
32    /// Attach an error code to an error
33    pub fn new(error: anyhow::Error, code: i32) -> CliError {
34        CliError {
35            error: Some(error),
36            exit_code: code,
37        }
38    }
39
40    /// Silent error
41    pub fn code(code: i32) -> CliError {
42        CliError {
43            error: None,
44            exit_code: code,
45        }
46    }
47}
48
49impl From<anyhow::Error> for CliError {
50    fn from(err: anyhow::Error) -> CliError {
51        CliError::new(err, 101)
52    }
53}
54
55impl From<clap::Error> for CliError {
56    fn from(err: clap::Error) -> CliError {
57        let code = if err.use_stderr() { 1 } else { 0 };
58        CliError::new(err.into(), code)
59    }
60}
61
62impl From<std::io::Error> for CliError {
63    fn from(err: std::io::Error) -> CliError {
64        CliError::new(err.into(), 1)
65    }
66}
67
68pub(crate) fn no_crate_err(name: impl Display) -> Error {
69    anyhow::format_err!("The crate `{}` could not be found in registry index.", name)
70}
71
72pub(crate) fn parse_manifest_err() -> Error {
73    anyhow::format_err!("Unable to parse external Cargo.toml")
74}
75
76pub(crate) fn non_existent_table_err(table: impl Display) -> Error {
77    anyhow::format_err!("The table `{}` could not be found.", table)
78}
79
80pub(crate) fn non_existent_dependency_err(name: impl Display, table: impl Display) -> Error {
81    anyhow::format_err!(
82        "The dependency `{}` could not be found in `{}`.",
83        name,
84        table,
85    )
86}
87
88pub(crate) fn invalid_cargo_config() -> Error {
89    anyhow::format_err!("Invalid cargo config")
90}
91
92pub(crate) fn unsupported_version_req(req: impl Display) -> Error {
93    anyhow::format_err!("Support for modifying {} is currently unsupported", req)
94}
95
96pub(crate) fn invalid_release_level(actual: impl Display, version: impl Display) -> Error {
97    anyhow::format_err!("Cannot increment the {} field for {}", actual, version)
98}
99
100pub(crate) fn parse_version_err(version: impl Display, dep: impl Display) -> Error {
101    anyhow::format_err!(
102        "The version `{}` for the dependency `{}` couldn't be parsed",
103        version,
104        dep
105    )
106}