Enabling #[serde(default)]
Added de-serialization from a js_sys::Map. This makes it easier to use data from the result of DurableObject::load().
Having #[serde(default)] enables a simple, yet effective data migration.
This makes it easier to use data from the result of
DurableObject::load().
I don't know what this is a reference to / what is DurableObject.
I agree serde(default) is useful and should work, but I don't feel comfortable mixing up dynamic types even further. Maps should be deserialized to maps, objects should be deserialized to structs. Is it possible to enable serde(default) without allowing arbitrary object -> map conversions?
Apologies, but it's been 3 weeks since I put the PR and I had to re-read it.
Are you concerned about a JS Map being deserialized into a Rust Struct instead of a Rust HashMap? Arguably it's more correct for a JS Map to be deserialized into a Struct due to the JS Map's variable value types. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#objects_vs._maps
Apologies, but it's been 3 weeks since I put the PR and I had to re-read it.
Yeah sorry looks like I accidentally unsubscribed from the repo.
Are you concerned about a JS Map being deserialized into a Rust Struct instead of a Rust HashMap?
Yes.
Arguably it's more correct for a JS Map to be deserialized into a Struct due to the JS Map's variable value types.
I disagree, Map is still closer to HashMap / BTreeMap / etc. due to dynamic nature of keys themselves. Any non-string keys can't be deserialized into non-string-keyed Maps, so semantically map-to-map is a more correct conversion.
If someone wants to use dynamic values in JS Map and deserialize those to Rust, they can do so by either using enums as a value, or a struct with custom Deserialize implementation. If someone really wants to deserialize Map to a struct, they can do so via deserialize_with (once that's fixed).
I just don't want a built-in conversion to mix types even further - at least some level of type checking is useful.
Any non-string keys can't be deserialized into non-string-keyed Maps, so semantically map-to-map is a more correct conversion.
Thank you for the explanation.
I'm in a situation where I save a JS Object via DurableObject::put() and later can retrieve it via DurableObject::list() as a Promise<Map<string, any>>. I'm trying to keep the WASM size small and avoid HashMaps altogether.
Having a custom deserializer for each struct that comes out of the DurableObject seems a bit much. Is there another option?
I think the fundamental difference is that I think any JS iterable should be able to be deserialized into a Rust struct.
Is there another option?
You can get result of durableObject.list() and invoke Object.fromEntries(...) on it - either on JS side or via wasm-bindgen - before passing to serde-wasm-bindgen. This can be done generically regardless of specific object type.
Removing this section will prevent the Map deserializing into an Object. Is there anything else needed for the PR?
It's hard to tell without seeing the whole / final diff. Please update the PR and I'll review as soon as I can.
Fixed, including the mentioned concerns, in an alternative implementation in https://github.com/cloudflare/serde-wasm-bindgen/commit/bf15072c58ec1a8228e8afc1dbab41b6818fc49b.