-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Map serde support #45
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
Could you add serialization tests for maps that show the JSON output directly? Like those tests: https://github.com/CosmWasm/serde-json-wasm/blob/v0.4.1/src/ser/mod.rs#L877-L980
Beautiful. Diff LGTM. Could you add a CHANGELOG entry to the unreleased section above 0.4.1 for this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your contribution and it looks promising.
I still see a number of unreachable!()
(which should really be todo!()
, right?) and I would love a few more tests to show what cases it can handle.
@@ -172,6 +179,9 @@ mod test { | |||
author: Address("[email protected]".to_owned()), | |||
}); | |||
|
|||
let mut balances: BTreeMap<String, u16> = BTreeMap::new(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, so this test will show parse(serialize(x)) == x
right?
And does work with u16
as tree value, which is promising.
Maybe other pieces already work. Can you add test cases for other types?
Also, this only works when the map has all the same type of value, right? I guess we need some more work for flatten, but we can leave that for another PR.
I pushed a HashMap test here. This shows it works and has non-deterministic ordering (as expected). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested serializing non string keys with
// non-string keys
let mut map = BTreeMap::new();
map.insert(123, "abc");
assert_eq!(to_string(&map).unwrap(), r#"{123:"abc"}"#);
Turns out this works in the current implementation, but is wrong since JSON can only accept string keys. So we should restrict it to keys that are string or char.
serde_json handles this by creating a MapKeySerializer
that only accepts string types as keys: https://github.com/serde-rs/json/blob/993e7a6eeaa89b39329d245e63879d7913ed1a41/src/ser.rs#L774-L1103. It is a wrapper around ser: &'a mut Serializer<W, F>,
that either fails or passes the serialization to ser
. It is constructed temporarily in serialize_key: key.serialize(MapKeySerializer { ser: *ser })
.
I think we should have this too to ensure users do not accidentally produce invalid JSON.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, like tests - seems to be working. The HashMap tests are not very interesting from the CW POV (because random state hashing not being useful in CW I think), but may be helpful in another non-fp application.
Actually in Wasm the random state hashing is disabled. The point here is that the serialization is as deterministic or undeterministic as the map's iteration order. The serializer DOES NOT sort keys. |
@CyberHoward do you want to work on the MapKeySerializer issue brought up in #45 (review)? Or should we merge here and I do it myself in a separate PR? Both ways are fine with me. |
Exactly that was what I meant by that, but I haven't this tweet anywhere in my bookmarks, so I didn't want to make too strong claims not to be wrong. |
Sure, I'll try to do it! |
The implementation in serde_json parses number types ( Also FYI new type |
Great stuff. I'd go with best possible serde_json compatibility, such that map created with our lib can be decoded using serde_json and vice versa. But we only need to support a subset of serde_json. Serializing the number types to string does no harm IMO and might be useful for some users. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great stuff.
I'd like to spend an hour this week to add a bunch of additional tests but other than that, this looks complete to me.
Deserialization into number key types is missing so this test fails:
Also the |
Could you add that too?
This is just the default implementation which deserializer implementations then override. It is added there for compatibility reasons because the first version of the trait did not have 128 bit. I think we can just implement it and then test deserializing with serde_json in a test. |
I think the sanity check is failing due to the outdated Rust version. |
Right, see #47. Thanks for the hint. |
Nice updates @CyberHoward ! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just added a bunch of additional tests. This looks great.
Will merge manually now to resolve the conflicts. Thanks a lot for the contribution!
Attempt to add serde support to map types.
Changes based on serde-json-core
closes #41