rustwasm / wasm-bindgen

Facilitating high-level interactions between Wasm modules and JavaScript
https://rustwasm.github.io/docs/wasm-bindgen/
Apache License 2.0
7.61k stars 1.05k forks source link

Deserializing JsValue results in "implementation of _IMPL_DESERIALIZE_FOR_CDDL::_serde::Deserialize is not general enough" error #2094

Open anweiss opened 4 years ago

anweiss commented 4 years ago

Describe the Bug

According to the docs, a JsValue can be deserialized into all types that implement the serde::de::Deserialize<'a> trait. I take this to mean that I should be able to deserialize a JsValue into types with borrowed fields. However, when attempting to do so, I get an error.

Steps to Reproduce

pub fn deserialize_test(jsValue: &JsValue) {
  let myType: MyType = jsValue.into_serde().unwrap();
}
implementation of `jsValue::_IMPL_DESERIALIZE_FOR_CDDL::_serde::Deserialize` is not general enough

MyType includes borrowed fields, opted in via #[serde(borrow)].

However, if I use serde_json directly, it seems to work:

pub fn deserialize_test(jsValue: &JsValue) {
  let myType: MyType = serde_json::from_str(&jsValue.as_string().unwrap()).unwrap();
}

Expected Behavior

I expected a JsValue to be deserializable into a type with borrowed fields using the into_json() method.

Actual Behavior

I am unable to deserialize a JsValue into a type with borrowed fields using the into_json() method.

Pauan commented 4 years ago

@anweiss Could you share the definition of your MyType?

anweiss commented 4 years ago

@Pauan sure thing. This is the type

anweiss commented 4 years ago

For additional context, I'd ultimately like to avoid having to derive Serialize and Deserialize and just append #[wasm_bindgen] to my types so I can get proper type declarations and avoid unnecessary serialization/deserialization. However, since structs with #[wasm_bindgen] cannot have lifetime nor type parameters, I'm faced with either deriving Serialize and Deserialize or duplicating a ton of code with owned fields in order to support wasm.