1use std::error::Error;
7use std::fmt;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
11#[non_exhaustive]
12pub enum Area {
13 Cfg,
15 Res,
17 Reg,
19 Prov,
21 Net,
23 Vrf,
25 Store,
27 Inst,
29 Env,
31 Lock,
33 Sys,
35 Int,
37}
38
39impl Area {
40 pub fn as_str(self) -> &'static str {
42 match self {
43 Area::Cfg => "CFG",
44 Area::Res => "RES",
45 Area::Reg => "REG",
46 Area::Prov => "PROV",
47 Area::Net => "NET",
48 Area::Vrf => "VRF",
49 Area::Store => "STORE",
50 Area::Inst => "INST",
51 Area::Env => "ENV",
52 Area::Lock => "LOCK",
53 Area::Sys => "SYS",
54 Area::Int => "INT",
55 }
56 }
57
58 pub fn exit(self) -> ExitCode {
60 match self {
61 Area::Cfg => ExitCode::Config,
62 Area::Res => ExitCode::Resolve,
63 Area::Reg | Area::Net => ExitCode::Network,
64 Area::Vrf => ExitCode::Verify,
65 Area::Store | Area::Inst | Area::Lock => ExitCode::Store,
66 Area::Prov | Area::Env | Area::Sys | Area::Int => ExitCode::Failure,
67 }
68 }
69}
70
71impl fmt::Display for Area {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 f.write_str(self.as_str())
74 }
75}
76
77#[derive(Debug, Clone, Copy, PartialEq, Eq)]
79#[non_exhaustive]
80pub enum ExitCode {
81 Ok = 0,
82 Failure = 1,
83 Usage = 2,
84 Config = 3,
85 Resolve = 4,
86 Network = 5,
87 Verify = 6,
88 Store = 7,
89 NotFound = 8,
90 Trust = 9,
91}
92
93impl ExitCode {
94 pub fn as_i32(self) -> i32 {
96 self as i32
97 }
98}
99
100#[derive(Debug)]
102pub struct VtaError {
103 pub area: Area,
105 pub number: u16,
107 pub message: String,
109 pub source: Option<Box<dyn Error + Send + Sync>>,
111}
112
113impl VtaError {
114 pub fn new(area: Area, number: u16, message: impl Into<String>) -> Self {
116 VtaError {
117 area,
118 number,
119 message: message.into(),
120 source: None,
121 }
122 }
123
124 pub fn with_source(mut self, source: impl Error + Send + Sync + 'static) -> Self {
126 self.source = Some(Box::new(source));
127 self
128 }
129
130 pub fn code(&self) -> String {
132 format!("VTA-{}-{:04}", self.area.as_str(), self.number)
133 }
134
135 pub fn exit(&self) -> ExitCode {
137 self.area.exit()
138 }
139}
140
141impl fmt::Display for VtaError {
142 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143 write!(f, "error[{}]: {}", self.code(), self.message)
144 }
145}
146
147impl Error for VtaError {
148 fn source(&self) -> Option<&(dyn Error + 'static)> {
149 self.source
150 .as_ref()
151 .map(|s| s.as_ref() as &(dyn Error + 'static))
152 }
153}
154
155pub type VtaResult<T> = Result<T, VtaError>;