use std::error::Error;
use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Area {
Cfg,
Res,
Reg,
Prov,
Net,
Vrf,
Store,
Inst,
Env,
Lock,
Sys,
Int,
}
impl Area {
pub fn as_str(self) -> &'static str {
match self {
Area::Cfg => "CFG",
Area::Res => "RES",
Area::Reg => "REG",
Area::Prov => "PROV",
Area::Net => "NET",
Area::Vrf => "VRF",
Area::Store => "STORE",
Area::Inst => "INST",
Area::Env => "ENV",
Area::Lock => "LOCK",
Area::Sys => "SYS",
Area::Int => "INT",
}
}
pub fn exit(self) -> ExitCode {
match self {
Area::Cfg => ExitCode::Config,
Area::Res => ExitCode::Resolve,
Area::Reg | Area::Net => ExitCode::Network,
Area::Vrf => ExitCode::Verify,
Area::Store | Area::Inst | Area::Lock => ExitCode::Store,
Area::Prov | Area::Env | Area::Sys | Area::Int => ExitCode::Failure,
}
}
}
impl fmt::Display for Area {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum ExitCode {
Ok = 0,
Failure = 1,
Usage = 2,
Config = 3,
Resolve = 4,
Network = 5,
Verify = 6,
Store = 7,
NotFound = 8,
Trust = 9,
}
impl ExitCode {
pub fn as_i32(self) -> i32 {
self as i32
}
}
#[derive(Debug)]
pub struct VtaError {
pub area: Area,
pub number: u16,
pub message: String,
pub source: Option<Box<dyn Error + Send + Sync>>,
}
impl VtaError {
pub fn new(area: Area, number: u16, message: impl Into<String>) -> Self {
VtaError {
area,
number,
message: message.into(),
source: None,
}
}
pub fn with_source(mut self, source: impl Error + Send + Sync + 'static) -> Self {
self.source = Some(Box::new(source));
self
}
pub fn code(&self) -> String {
format!("VTA-{}-{:04}", self.area.as_str(), self.number)
}
pub fn exit(&self) -> ExitCode {
self.area.exit()
}
}
impl fmt::Display for VtaError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "error[{}]: {}", self.code(), self.message)
}
}
impl Error for VtaError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
self.source
.as_ref()
.map(|s| s.as_ref() as &(dyn Error + 'static))
}
}
pub type VtaResult<T> = Result<T, VtaError>;