use std::error::Error;
use std::fmt;
use std::marker;
#[derive(Debug)]
pub struct I32Exit(pub i32);
impl fmt::Display for I32Exit {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Exited with i32 exit status {}", self.0)
}
}
impl std::error::Error for I32Exit {}
#[repr(transparent)]
pub struct TrappableError<T> {
err: wasmtime::Error,
_marker: marker::PhantomData<T>,
}
impl<T> TrappableError<T> {
pub fn trap(err: impl Into<wasmtime::Error>) -> TrappableError<T> {
TrappableError {
err: err.into(),
_marker: marker::PhantomData,
}
}
pub fn downcast(self) -> wasmtime::Result<T>
where
T: Error + Send + Sync + 'static,
{
self.err.downcast()
}
pub fn downcast_ref(&self) -> Option<&T>
where
T: Error + Send + Sync + 'static,
{
self.err.downcast_ref()
}
}
impl<T> From<T> for TrappableError<T>
where
T: Error + Send + Sync + 'static,
{
fn from(error: T) -> Self {
Self {
err: error.into(),
_marker: marker::PhantomData,
}
}
}
impl<T> fmt::Debug for TrappableError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.err.fmt(f)
}
}
impl<T> fmt::Display for TrappableError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.err.fmt(f)
}
}
impl<T> Error for TrappableError<T> {}