1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
use core::ops::{Deref, DerefMut}; use crate::describe::*; /// A trait for anything that can be converted into a type that can cross the /// wasm ABI directly, eg `u32` or `f64`. /// /// This is the opposite operation as `FromWasmAbi` and `Ref[Mut]FromWasmAbi`. pub trait IntoWasmAbi: WasmDescribe { /// The wasm ABI type that this converts into when crossing the ABI /// boundary. type Abi: WasmAbi; /// Convert `self` into `Self::Abi` so that it can be sent across the wasm /// ABI boundary. fn into_abi(self) -> Self::Abi; } /// A trait for anything that can be recovered by-value from the wasm ABI /// boundary, eg a Rust `u8` can be recovered from the wasm ABI `u32` type. /// /// This is the by-value variant of the opposite operation as `IntoWasmAbi`. pub trait FromWasmAbi: WasmDescribe { /// The wasm ABI type that this converts from when coming back out from the /// ABI boundary. type Abi: WasmAbi; /// Recover a `Self` from `Self::Abi`. /// /// # Safety /// /// This is only safe to call when -- and implementations may assume that -- /// the supplied `Self::Abi` was previously generated by a call to `<Self as /// IntoWasmAbi>::into_abi()` or the moral equivalent in JS. unsafe fn from_abi(js: Self::Abi) -> Self; } /// A trait for anything that can be recovered as some sort of shared reference /// from the wasm ABI boundary. /// /// This is the shared reference variant of the opposite operation as /// `IntoWasmAbi`. pub trait RefFromWasmAbi: WasmDescribe { /// The wasm ABI type references to `Self` are recovered from. type Abi: WasmAbi; /// The type that holds the reference to `Self` for the duration of the /// invocation of the function that has an `&Self` parameter. This is /// required to ensure that the lifetimes don't persist beyond one function /// call, and so that they remain anonymous. type Anchor: Deref<Target = Self>; /// Recover a `Self::Anchor` from `Self::Abi`. /// /// # Safety /// /// Same as `FromWasmAbi::from_abi`. unsafe fn ref_from_abi(js: Self::Abi) -> Self::Anchor; } /// Dual of the `RefFromWasmAbi` trait, except for mutable references. pub trait RefMutFromWasmAbi: WasmDescribe { /// Same as `RefFromWasmAbi::Abi` type Abi: WasmAbi; /// Same as `RefFromWasmAbi::Anchor` type Anchor: DerefMut<Target = Self>; /// Same as `RefFromWasmAbi::ref_from_abi` unsafe fn ref_mut_from_abi(js: Self::Abi) -> Self::Anchor; } /// Indicates that this type can be passed to JS as `Option<Self>`. /// /// This trait is used when implementing `IntoWasmAbi for Option<T>`. pub trait OptionIntoWasmAbi: IntoWasmAbi { /// Returns an ABI instance indicating "none", which JS will interpret as /// the `None` branch of this option. /// /// It should be guaranteed that the `IntoWasmAbi` can never produce the ABI /// value returned here. fn none() -> Self::Abi; } /// Indicates that this type can be received from JS as `Option<Self>`. /// /// This trait is used when implementing `FromWasmAbi for Option<T>`. pub trait OptionFromWasmAbi: FromWasmAbi { /// Tests whether the argument is a "none" instance. If so it will be /// deserialized as `None`, and otherwise it will be passed to /// `FromWasmAbi`. fn is_none(abi: &Self::Abi) -> bool; } /// An unsafe trait which represents types that are ABI-safe to pass via wasm /// arguments. /// /// This is an unsafe trait to implement as there's no guarantee the type is /// actually safe to transfer across the was boundary, it's up to you to /// guarantee this so codegen works correctly. pub unsafe trait WasmAbi {} unsafe impl WasmAbi for u32 {} unsafe impl WasmAbi for i32 {} unsafe impl WasmAbi for f32 {} unsafe impl WasmAbi for f64 {} /// A trait representing how to interepret the return value of a function for /// the wasm ABI. /// /// This is very similar to the `IntoWasmAbi` trait and in fact has a blanket /// implementation for all implementors of the `IntoWasmAbi`. The primary use /// case of this trait is to enable functions to return `Result`, interpreting /// an error as "rethrow this to JS" pub trait ReturnWasmAbi: WasmDescribe { /// Same as `IntoWasmAbi::Abi` type Abi: WasmAbi; /// Same as `IntoWasmAbi::into_abi`, except that it may throw and never /// return in the case of `Err`. fn return_abi(self) -> Self::Abi; } impl<T: IntoWasmAbi> ReturnWasmAbi for T { type Abi = T::Abi; fn return_abi(self) -> Self::Abi { self.into_abi() } }