cardanowall_cli/util/error.rs
1//! The CLI error type that drives the process exit code.
2//!
3//! Every subcommand handler returns `Result<(), CliError>`. A `CliError` carries
4//! the numeric exit code and an optional diagnostic message; `main` prints the
5//! message to stderr (prefixed `cardanowall: `) and exits with the code.
6//!
7//! Exit-code contract (the public UX, identical to the reference CLI):
8//!
9//! - `0` — success (verdict valid, or a non-verdict happy path).
10//! - `1` — integrity-class failure (verdict invalid, service-independence
11//! violation, server rejection).
12//! - `2` — network-class failure (unrecoverable runtime / IO / unparseable
13//! response).
14//! - `3` — pending (insufficient confirmations / unconfirmed tx).
15//! - `4` — CLI input error (bad args, malformed positional, conflicting modes).
16
17use std::fmt;
18
19/// A subcommand failure carrying its process exit code and a diagnostic.
20#[derive(Debug, Clone, PartialEq, Eq)]
21pub struct CliError {
22 /// The process exit code (`1`–`4`; `0` never travels as an error).
23 pub code: i32,
24 /// The diagnostic written to stderr. Empty for a silent non-zero exit.
25 pub message: String,
26}
27
28impl CliError {
29 /// Build an error with an explicit code and message.
30 pub fn new(code: i32, message: impl Into<String>) -> Self {
31 Self {
32 code,
33 message: message.into(),
34 }
35 }
36
37 /// A CLI input error (`4`): bad args, malformed positional, conflicting modes.
38 pub fn input(message: impl Into<String>) -> Self {
39 Self::new(4, message)
40 }
41
42 /// An integrity-class error (`1`): invalid verdict, server rejection.
43 pub fn integrity(message: impl Into<String>) -> Self {
44 Self::new(1, message)
45 }
46
47 /// A network-class error (`2`): IO / transport / unparseable response.
48 pub fn network(message: impl Into<String>) -> Self {
49 Self::new(2, message)
50 }
51}
52
53impl fmt::Display for CliError {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 write!(f, "{}", self.message)
56 }
57}
58
59impl std::error::Error for CliError {}