distributed-it-for-telco / distributed-rating-poc

Proof of concept illustrating a sample implementation of wasmCloud-based distributed rating
1 stars 1 forks source link

Can't use `serde` macros with `wit-bindgen additional_derives` #42

Open msabdelwahab opened 1 week ago

msabdelwahab commented 1 week ago

In Order to be able to send wit type to/from http requests, and redis store, we need to be able to serialize/deserialize the struct instance. serde is the de-facto crate for this in rust, which uses macro to auto-generate serialization logic for rust types. attempting to pass serde macros in the rust "wit-bindgen:generate" macro fails for some types

error[E0277]: the trait bound wasi::io::error::Error: Deserialize<'>is not satisfied --> src/lib.rs:5:1 | 5 | / wit_bindgen::generate!({ 6 | | world: "wasi-http-tests", 7 | | exports: { 8 | | "wasi-http-tests:component/client/wasi-http-tests-client": WasiHttpTestsClient, 9 | | }, 10 | | additional_derives: [serde::Serialize, serde::Deserialize] 11 | | }); | |__^ the traitDeserialize<'>is not implemented forwasi::io::error::Error| = help: the following other types implement traitDeserialize<'de>: bool char isize i8 i16 i32 i64 i128 and 137 others note: required by a bound in newtype_variant--> /Users/lnj/.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde-1.0.193/src/de/mod.rs:2119:12 | 2117 | fn newtype_variant(self) -> Result<T, Self::Error> | --------------- required by a bound in this associated function 2118 | where 2119 | T: Deserialize<'de>, | ^^^^^^^^^^^^^^^^ required by this bound inVariantAccess::newtype_variant= note: this error originates in the macrowit_bindgen::generate` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound wasi::io::error::Error: Serialize is not satisfied --> src/lib.rs:5:1 5 / wit_bindgen::generate!({ 6 world: "wasi-http-tests", 7 exports: { 8 "wasi-http-tests:component/client/wasi-http-tests-client": WasiHttpTestsClient, 9 }, 10 additional_derives: [serde::Serialize, serde::Deserialize] 11 }); __^ the trait Serialize is not implemented for wasi::io::error::Error

= help: the following other types implement trait Serialize: bool char isize i8 i16 i32 i64 i128 and 136 others note: required by a bound in serialize_newtype_variant --> /Users/lnj/.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde-1.0.193/src/ser/mod.rs:936:12 | 928 | fn serialize_newtype_variant<T: ?Sized>( | ------------------------- required by a bound in this associated function ... 936 | T: Serialize; | ^^^^^^^^^ required by this bound in Serializer::serialize_newtype_variant = note: this error originates in the macro wit_bindgen::generate (in Nightly builds, run with -Z macro-backtrace for more info) `

ahmed-m-rizk commented 5 days ago

We asked for support from cosmonic team on their slack channel. They confirmed that this is a real issue and they are already facing it, and made two suggestions, as quoted

I actually hit the same problem with wasi:http the other day trying to add derivations for Serialize and Deserialize. It turns out this is actually a bug in the way that derives are handled in wit-bindgen https://github.com/bytecodealliance/wit-bindgen/issues/812. The short version is that you can't add Serialize or Deserialize to a resource type, but wit-bindgen has no way to express that you don't want it to apply there. You have two options as far as I know: define an intermediate type that shadows the type you're defining in WIT and write helper functions to convert between the two types implement Serialize and Deserialize for any of the WIT types that you want without deriving them

ahmed-m-rizk commented 5 days ago

We investigated both approaches, and decided to proceed with the first approach, the reason is that it was found faster to code and less error prone