From 6281985127104650636a57d00b98ea50da41d1c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Gaspard?= Date: Tue, 27 Feb 2024 22:29:26 +0100 Subject: [PATCH] Fix map roundtrips in untagged enums (#64) --- src/de.rs | 9 ++++++--- tests/common/mod.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/de.rs b/src/de.rs index 9a1a75e..89be4ef 100644 --- a/src/de.rs +++ b/src/de.rs @@ -1,4 +1,4 @@ -use js_sys::{Array, ArrayBuffer, JsString, Number, Object, Symbol, Uint8Array}; +use js_sys::{Array, ArrayBuffer, JsString, Map, Number, Object, Symbol, Uint8Array}; use serde::de::value::{MapDeserializer, SeqDeserializer}; use serde::de::{self, IntoDeserializer}; use std::convert::TryFrom; @@ -317,12 +317,15 @@ impl<'de> de::Deserializer<'de> for Deserializer { // (see https://github.com/RReverser/serde-wasm-bindgen/pull/4#discussion_r352245020). // // We expect such enums to be represented via plain JS objects, so let's explicitly - // exclude Sets, Maps and any other iterables. These should be deserialized via concrete + // exclude Sets and other iterables. These should be deserialized via concrete // `deserialize_*` methods instead of us trying to guess the right target type. // + // We still do support Map, so that the format described here stays a self-describing + // format: we happen to serialize to Map, and it is not ambiguous. + // // Hopefully we can rid of these hacks altogether once // https://github.com/serde-rs/serde/issues/1183 is implemented / fixed on serde side. - !Symbol::iterator().js_in(&self.value) + (!Symbol::iterator().js_in(&self.value) || self.value.has_type::()) { self.deserialize_map(visitor) } else { diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 59e2380..b8895d2 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -13,6 +13,8 @@ use wasm_bindgen_test::wasm_bindgen_test; const SERIALIZER: Serializer = Serializer::new(); +const JSON_SERIALIZER: Serializer = Serializer::json_compatible(); + const BIGINT_SERIALIZER: Serializer = Serializer::new().serialize_large_number_types_as_bigints(true); @@ -664,6 +666,30 @@ fn enums() { } } +#[wasm_bindgen_test] +fn serde_json_value_with_json() { + test_via_round_trip_with_config( + serde_json::from_str::("[0, \"foo\"]").unwrap(), + &JSON_SERIALIZER, + ); + test_via_round_trip_with_config( + serde_json::from_str::(r#"{"foo": "bar"}"#).unwrap(), + &JSON_SERIALIZER, + ); +} + +#[wasm_bindgen_test] +fn serde_json_value_with_default() { + test_via_round_trip_with_config( + serde_json::from_str::("[0, \"foo\"]").unwrap(), + &SERIALIZER, + ); + test_via_round_trip_with_config( + serde_json::from_str::(r#"{"foo": "bar"}"#).unwrap(), + &SERIALIZER, + ); +} + #[wasm_bindgen_test] fn preserved_value() { #[derive(serde::Deserialize, serde::Serialize, PartialEq, Clone, Debug)]