use thiserror::Error;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum RecoveryCategory {
InvalidInput,
Unsupported,
InternalInvariant,
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum Diagnostic {
#[error("operation {operation} at {location}: {reason}")]
InvalidOperation {
operation: String,
location: String,
reason: &'static str,
},
#[error("cannot represent {operation}: {reason}")]
Unsupported {
operation: String,
reason: &'static str,
},
}
impl Diagnostic {
pub fn from_error(error: &pliron::result::Error) -> Option<&Self> {
let mut source: &dyn std::error::Error = error;
loop {
if let Some(diagnostic) = source.downcast_ref::<Self>() {
return Some(diagnostic);
}
source = if let Some(envelope) = source.downcast_ref::<pliron::result::Error>() {
envelope.err.as_ref()
} else {
source.source()?
};
}
}
pub fn recovery_category(&self) -> RecoveryCategory {
match self {
Self::InvalidOperation { .. } => RecoveryCategory::InvalidInput,
Self::Unsupported { .. } => RecoveryCategory::Unsupported,
}
}
}
impl From<crate::attributes::EnumParseError> for pliron::result::Error {
fn from(error: crate::attributes::EnumParseError) -> Self {
pliron::arg_error_noloc!(error)
}
}
impl From<crate::attributes::EnumValueError> for pliron::result::Error {
fn from(error: crate::attributes::EnumValueError) -> Self {
pliron::arg_error_noloc!(error)
}
}
impl From<Diagnostic> for pliron::result::Error {
fn from(diagnostic: Diagnostic) -> Self {
pliron::arg_error_noloc!(diagnostic)
}
}