1 use std::error::Error; 2 use std::fmt; 3 use std::marker; 4 5 /// An error returned from the `proc_exit` host syscall. 6 /// 7 /// Embedders can test if an error returned from wasm is this error, in which 8 /// case it may signal a non-fatal trap. 9 #[derive(Debug)] 10 pub struct I32Exit(pub i32); 11 12 impl fmt::Display for I32Exit { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result13 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 14 write!(f, "Exited with i32 exit status {}", self.0) 15 } 16 } 17 18 impl std::error::Error for I32Exit {} 19 20 /// A helper error type used by many other modules through type aliases. 21 /// 22 /// This type is an `Error` itself and is intended to be a representation of 23 /// either: 24 /// 25 /// * A custom error type `T` 26 /// * A trap, represented as `wasmtime::Error` 27 /// 28 /// This error is created through either the `::trap` constructor representing a 29 /// full-fledged trap or the `From<T>` constructor which is intended to be used 30 /// with `?`. The goal is to make normal errors `T` "automatic" but enable error 31 /// paths to return a `::trap` error optionally still as necessary without extra 32 /// boilerplate everywhere else. 33 /// 34 /// Note that this type isn't used directly but instead is intended to be used 35 /// as: 36 /// 37 /// ```rust,ignore 38 /// type MyError = TrappableError<bindgen::TheError>; 39 /// ``` 40 /// 41 /// where `MyError` is what you'll use throughout bindings code and 42 /// `bindgen::TheError` is the type that this represents as generated by the 43 /// `bindgen!` macro. 44 #[repr(transparent)] 45 pub struct TrappableError<T> { 46 err: wasmtime::Error, 47 _marker: marker::PhantomData<T>, 48 } 49 50 impl<T> TrappableError<T> { trap(err: impl Into<wasmtime::Error>) -> TrappableError<T>51 pub fn trap(err: impl Into<wasmtime::Error>) -> TrappableError<T> { 52 TrappableError { 53 err: err.into(), 54 _marker: marker::PhantomData, 55 } 56 } 57 downcast(self) -> wasmtime::Result<T> where T: Error + Send + Sync + 'static,58 pub fn downcast(self) -> wasmtime::Result<T> 59 where 60 T: Error + Send + Sync + 'static, 61 { 62 self.err.downcast() 63 } 64 downcast_ref(&self) -> Option<&T> where T: Error + Send + Sync + 'static,65 pub fn downcast_ref(&self) -> Option<&T> 66 where 67 T: Error + Send + Sync + 'static, 68 { 69 self.err.downcast_ref() 70 } 71 } 72 73 impl<T> From<T> for TrappableError<T> 74 where 75 T: Error + Send + Sync + 'static, 76 { from(error: T) -> Self77 fn from(error: T) -> Self { 78 Self { 79 err: error.into(), 80 _marker: marker::PhantomData, 81 } 82 } 83 } 84 85 impl<T> fmt::Debug for TrappableError<T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result86 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 87 self.err.fmt(f) 88 } 89 } 90 91 impl<T> fmt::Display for TrappableError<T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result92 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 93 self.err.fmt(f) 94 } 95 } 96 97 impl<T> Error for TrappableError<T> {} 98