//! This module contains auxilary functions which one might find useful for //! generating implementations of host related functionality like `Externals`. use nan_preserving_float::{F32, F64}; use {RuntimeValue, Trap, ValueType}; /// A trait that represents a value that can be directly coerced to one of /// wasm base value types. pub trait IntoWasmValue { /// The value type into which the self type is converted. const VALUE_TYPE: ValueType; /// Perform the conversion. fn into_wasm_value(self) -> RuntimeValue; } macro_rules! impl_convertible_to_wasm { // TODO: Replace it to Kleene ? operator ($ty:ty, $wasm_ty:ident $(, as $cast_to:ty)* ) => { impl IntoWasmValue for $ty { const VALUE_TYPE: ValueType = ValueType::$wasm_ty; fn into_wasm_value(self) -> RuntimeValue { RuntimeValue::$wasm_ty(self $( as $cast_to)*) } } }; } impl_convertible_to_wasm!(i32, I32); impl_convertible_to_wasm!(u32, I32, as i32); impl_convertible_to_wasm!(i64, I64); impl_convertible_to_wasm!(u64, I64, as i64); impl_convertible_to_wasm!(F32, F32); impl_convertible_to_wasm!(F64, F64); /// A trait that represents a value that can be returned from a function. /// /// Basically it is superset of `IntoWasmValue` types, adding the ability to return /// the unit value (i.e. `()`) and return a value that signals a trap. pub trait IntoWasmResult { /// The value type into which the self type is converted or `None` in case /// of the unit value (aka `()` aka `void`). const VALUE_TYPE: Option; /// Perform the conversion. fn into_wasm_result(self) -> Result, Trap>; } impl IntoWasmResult for () { const VALUE_TYPE: Option = None; fn into_wasm_result(self) -> Result, Trap> { Ok(None) } } impl> IntoWasmResult for Result { const VALUE_TYPE: Option = Some(R::VALUE_TYPE); fn into_wasm_result(self) -> Result, Trap> { self.map(|v| Some(v.into_wasm_value())).map_err(Into::into) } } impl> IntoWasmResult for Result<(), E> { const VALUE_TYPE: Option = None; fn into_wasm_result(self) -> Result, Trap> { self.map(|_| None).map_err(Into::into) } } impl IntoWasmResult for R { const VALUE_TYPE: Option = Some(R::VALUE_TYPE); fn into_wasm_result(self) -> Result, Trap> { Ok(Some(self.into_wasm_value())) } }