use std::fmt;
use std::path::PathBuf;
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum VitriError {
Config {
reason: String,
},
Spec {
spec: String,
reason: String,
},
Env {
var: &'static str,
reason: String,
},
Input {
reason: String,
},
Mismatch {
reason: String,
},
Construction {
spec: String,
reason: String,
},
Io {
path: PathBuf,
action: &'static str,
reason: String,
},
}
impl VitriError {
pub fn spec(spec: impl Into<String>, reason: impl Into<String>) -> Self {
VitriError::Spec {
spec: spec.into(),
reason: reason.into(),
}
}
pub fn env(var: &'static str, reason: impl Into<String>) -> Self {
VitriError::Env {
var,
reason: reason.into(),
}
}
pub fn config(reason: impl Into<String>) -> Self {
VitriError::Config {
reason: reason.into(),
}
}
pub fn input(reason: impl Into<String>) -> Self {
VitriError::Input {
reason: reason.into(),
}
}
pub fn mismatch(reason: impl Into<String>) -> Self {
VitriError::Mismatch {
reason: reason.into(),
}
}
pub fn construction(spec: impl Into<String>, reason: impl Into<String>) -> Self {
VitriError::Construction {
spec: spec.into(),
reason: reason.into(),
}
}
pub fn io(path: impl Into<PathBuf>, action: &'static str, source: &std::io::Error) -> Self {
VitriError::Io {
path: path.into(),
action,
reason: source.to_string(),
}
}
}
impl fmt::Display for VitriError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
VitriError::Config { reason } => write!(f, "{reason}"),
VitriError::Spec { spec, reason } => write!(f, "vtree spec '{spec}': {reason}"),
VitriError::Env { var, reason } => write!(f, "environment variable {var}: {reason}"),
VitriError::Input { reason } => write!(f, "{reason}"),
VitriError::Mismatch { reason } => write!(f, "{reason}"),
VitriError::Construction { spec, reason } => write!(f, "{spec} failed: {reason}"),
VitriError::Io {
path,
action,
reason,
} => write!(f, "cannot {action} {}: {reason}", path.display()),
}
}
}
impl std::error::Error for VitriError {}
pub(crate) fn from_construction<T>(
result: Result<T, String>,
spec: impl fmt::Display,
) -> Result<T, VitriError> {
result.map_err(|reason| VitriError::construction(spec.to_string(), reason))
}