use std::error::Error; use std::fmt; use std::marker; /// An error returned from the `proc_exit` host syscall. /// /// Embedders can test if an error returned from wasm is this error, in which /// case it may signal a non-fatal trap. #[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 {} /// A helper error type used by many other modules through type aliases. /// /// This type is an `Error` itself and is intended to be a representation of /// either: /// /// * A custom error type `T` /// * A trap, represented as `wasmtime::Error` /// /// This error is created through either the `::trap` constructor representing a /// full-fledged trap or the `From` constructor which is intended to be used /// with `?`. The goal is to make normal errors `T` "automatic" but enable error /// paths to return a `::trap` error optionally still as necessary without extra /// boilerplate everywhere else. /// /// Note that this type isn't used directly but instead is intended to be used /// as: /// /// ```rust,ignore /// type MyError = TrappableError; /// ``` /// /// where `MyError` is what you'll use throughout bindings code and /// `bindgen::TheError` is the type that this represents as generated by the /// `bindgen!` macro. #[repr(transparent)] pub struct TrappableError { err: wasmtime::Error, _marker: marker::PhantomData, } impl TrappableError { pub fn trap(err: impl Into) -> TrappableError { TrappableError { err: err.into(), _marker: marker::PhantomData, } } pub fn downcast(self) -> wasmtime::Result 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 From for TrappableError where T: Error + Send + Sync + 'static, { fn from(error: T) -> Self { Self { err: error.into(), _marker: marker::PhantomData, } } } impl fmt::Debug for TrappableError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.err.fmt(f) } } impl fmt::Display for TrappableError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.err.fmt(f) } } impl Error for TrappableError {}