Refactor FFI error handling

To reduce verbosity and duplication.
This commit is contained in:
Oliver Hamlet
2025-04-22 18:39:13 +01:00
parent 5c871bdf0c
commit d648011e51
9 changed files with 121 additions and 198 deletions
+59 -1
View File
@@ -29,7 +29,19 @@ pub enum SystemErrorCategory {
LootConditionInterpreter = LIBLOOT_SYSTEM_ERROR_CATEGORY_LCI,
}
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
impl std::fmt::Display for SystemErrorCategory {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
SystemErrorCategory::Esplugin => write!(f, "esplugin"),
SystemErrorCategory::Libloadorder => write!(f, "libloadorder"),
SystemErrorCategory::LootConditionInterpreter => {
write!(f, "loot-condition-interpreter")
}
}
}
}
#[derive(Debug)]
pub struct SystemError {
code: c_int,
category: SystemErrorCategory,
@@ -50,6 +62,18 @@ impl SystemError {
}
}
impl std::fmt::Display for SystemError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{} error, code {}: {}",
self.category, self.code, self.message
)
}
}
impl std::error::Error for SystemError {}
impl From<PluginDataError> for SystemError {
fn from(value: PluginDataError) -> Self {
let error = value
@@ -97,3 +121,37 @@ impl From<ConditionEvaluationError> for SystemError {
}
}
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct UnsupportedEnumValueError;
impl std::fmt::Display for UnsupportedEnumValueError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Enum value is unsupported")
}
}
impl std::error::Error for UnsupportedEnumValueError {}
pub fn fmt_error_chain(
mut error: &dyn std::error::Error,
f: &mut std::fmt::Formatter<'_>,
) -> std::fmt::Result {
write!(f, "{}", error)?;
while let Some(source) = error.source() {
write!(f, ": {}", source)?;
error = source;
}
Ok(())
}
#[macro_export]
macro_rules! variant_box_from_error {
( $from_type:ident, $to_type:ident::$to_variant:ident ) => {
impl From<$from_type> for $to_type {
fn from(value: $from_type) -> Self {
Self::$to_variant(Box::new(value))
}
}
};
}