use std::path::PathBuf;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum ResourceLimit {
MaxOperations,
MaxCallLevels,
MaxExprDepth,
MaxStringSize,
MaxArraySize,
MaxMapSize,
}
impl ResourceLimit {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::MaxOperations => "max_operations",
Self::MaxCallLevels => "max_call_levels",
Self::MaxExprDepth => "max_expr_depth",
Self::MaxStringSize => "max_string_size",
Self::MaxArraySize => "max_array_size",
Self::MaxMapSize => "max_map_size",
}
}
}
impl std::fmt::Display for ResourceLimit {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum PluginError {
Compile { path: PathBuf, message: String },
Runtime { id: String, message: String },
ResourceExceeded { id: String, limit: ResourceLimit },
Timeout { id: String },
MalformedReturn { id: String, message: String },
UnknownDataDep { path: PathBuf, name: String },
MalformedDataDeps { path: PathBuf, message: String },
IdCollision {
id: String,
winner: CollisionWinner,
loser_path: PathBuf,
},
}
impl PluginError {
#[must_use]
pub fn kind(&self) -> &'static str {
match self {
Self::Compile { .. } => "Compile",
Self::Runtime { .. } => "Runtime",
Self::ResourceExceeded { .. } => "ResourceExceeded",
Self::Timeout { .. } => "Timeout",
Self::MalformedReturn { .. } => "MalformedReturn",
Self::UnknownDataDep { .. } => "UnknownDataDep",
Self::MalformedDataDeps { .. } => "MalformedDataDeps",
Self::IdCollision { .. } => "IdCollision",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CollisionWinner {
BuiltIn,
Plugin(PathBuf),
}
impl std::fmt::Display for CollisionWinner {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::BuiltIn => f.write_str("<built-in>"),
Self::Plugin(p) => f.write_str(&p.display().to_string()),
}
}
}
impl std::fmt::Display for PluginError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Compile { path, message } => {
write!(f, "compile error in {}: {message}", path.display())
}
Self::Runtime { id, message } => {
write!(f, "plugin {id} runtime error: {message}")
}
Self::ResourceExceeded { id, limit } => {
write!(f, "plugin {id} exceeded {limit}")
}
Self::Timeout { id } => write!(f, "plugin {id} timed out"),
Self::MalformedReturn { id, message } => {
write!(f, "plugin {id} returned malformed value: {message}")
}
Self::UnknownDataDep { path, name } => {
write!(
f,
"plugin at {} declares unknown @data_deps entry `{name}`",
path.display()
)
}
Self::MalformedDataDeps { path, message } => {
write!(
f,
"plugin at {} has malformed @data_deps header: {message}",
path.display()
)
}
Self::IdCollision {
id,
winner,
loser_path,
} => write!(
f,
"plugin id `{id}` collision: kept {winner}, rejected {}",
loser_path.display()
),
}
}
}
impl std::error::Error for PluginError {}