The current approach for marshaling values between Rust and C# is syntax-based, requiring that the #[cs_bindgen] proc macro be able to recognize argument/return types so that it can generate the correct conversions. This was a simple approach to get us started, but has numerous drawbacks that ultimately can't be resolved with a syntax-based approach. Instead, we should switch to a trait-based approach.
The trait-based approach has two main parts:
On the Rust side, the trait defines the ABI-compatible type corresponding to the Rust type, and contains the logic necessary for converting between the two. The code generated by #[cs_bindgen] delegates to the trait implementation for the type without needing to know anything about the type itself.
On the C# side, we include functions in the generated Wasm module that allow the C# code generator to extract the type information and generate the appropriate binding code.
The current approach for marshaling values between Rust and C# is syntax-based, requiring that the
#[cs_bindgen]
proc macro be able to recognize argument/return types so that it can generate the correct conversions. This was a simple approach to get us started, but has numerous drawbacks that ultimately can't be resolved with a syntax-based approach. Instead, we should switch to a trait-based approach.The trait-based approach has two main parts:
#[cs_bindgen]
delegates to the trait implementation for the type without needing to know anything about the type itself.This approach is based off how wasm-bindgen handles generating bindings for complex Rust types. We should take a similar approach as much as possible, while striving to keep our implementation generalized beyond C# as much as possible.