use std::ffi::{OsStr, OsString};
use std::fmt;
#[derive(Debug)]
pub enum EngineError {
#[cfg(feature = "store")]
Kit(crate_plugin_kit::KitError),
NotFound(String),
Usage(String),
Setup(String),
NoProject(String),
Detect(pmpx_detect::DetectFailure),
Call {
plugin: String,
verb: String,
error: pmpx_loader::CallError,
},
Start {
program: OsString,
source: std::io::Error,
},
}
impl EngineError {
pub(crate) fn not_found(message: String) -> Self {
Self::NotFound(message)
}
pub fn message(&self) -> String {
match self {
#[cfg(feature = "store")]
Self::Kit(error) => error.to_string(),
Self::NotFound(message) | Self::Usage(message) | Self::Setup(message) => {
message.clone()
}
Self::NoProject(message) => message.clone(),
Self::Detect(failure) => failure.message(),
Self::Call {
plugin,
verb,
error,
} => format!("plugin {plugin} cannot do `{verb}`: {error}"),
Self::Start { program, source } => {
format!("failed to start {}: {source}", program.to_string_lossy())
}
}
}
pub fn program(&self) -> Option<&OsStr> {
match self {
Self::Start { program, .. } => Some(program),
_ => None,
}
}
pub fn is_not_found(&self) -> bool {
matches!(
self,
Self::NotFound(_) | Self::NoProject(_) | Self::Setup(_)
)
}
}
impl fmt::Display for EngineError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.message())
}
}
impl std::error::Error for EngineError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Start { source, .. } => Some(source),
#[cfg(feature = "store")]
Self::Kit(error) => Some(error),
_ => None,
}
}
}
#[cfg(feature = "store")]
impl From<crate_plugin_kit::KitError> for EngineError {
fn from(error: crate_plugin_kit::KitError) -> Self {
Self::Kit(error)
}
}
pub(crate) type Result<T> = std::result::Result<T, EngineError>;