-
-
Notifications
You must be signed in to change notification settings - Fork 793
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
Option<()> value doesn't round trip through JSON #1690
Comments
Be aware that neither serde nor serde_json makes round trip guarantees in general. What JSON would you expect to get for each of the two values? |
Good to know, though now you've got me worried. Is there any documentation I can follow? I wonder what are other known cases where round trip fails for built-in serialization formats?
Now things fail for any optional value that serializies to null. Either But then — this likely should be consistent for all unit-like types, like For now I guess I can try using something like |
I'm a newbie and this issue also got me using an optional unit struct: use serde::{Deserialize, Serialize};
#[derive(Deserialize, Debug, Serialize, PartialEq)]
struct Player;
#[derive(Deserialize, Debug, Serialize, PartialEq)]
struct Components {
player: Option<Player>
}
fn main() {
let player = Player {};
let player_str = &serde_json::to_string(&player).unwrap();
println!("{}", player_str); // `null`, I was thinking an empty object but ok.
let player_deser: Player = serde_json::from_str(player_str).unwrap();
println!("{:?}", &player_deser); // `Player`, that's good.
assert_eq!(player_deser, player);
let components = Components {player: Some(player)};
let components_str = &serde_json::to_string(&components).unwrap();
println!("{}", components_str); // `{"player":null}`, I'm not sure how to specify None but ok.
let components_deser: Components = serde_json::from_str(components_str).unwrap();
println!("{:?}", &components_deser); // `Components { player: None }`, oh no! The issue is that I can't specify Some!
// The next line fails:
// thread 'main' panicked at 'assertion failed: `(left == right)`
// left: `Components { player: Some(Player) }`,
// right: `Components { player: None }`', src/main.rs:29:5
assert_eq!(components, components_deser);
}
There may be very practical reasons for this but I was especially surprised to read it as I normally verify serialization and deserialization by testing that an arbitrary input makes the roundtrip. E.g., input == deserialize(serialize(input)) in other languages. Thank you contributors for your continued hard work on this library! It's great 👍 💯 Edit (2020-03-31): I stumbled upon a more relevant example from a related Rust de/serialization library that does support roundtrips, bincode. |
Please consider the following:
I have a value of
Option<()>
type. However, serde_json serializes both its values (i.e.Some(())
andNone
) asnull
— that gets deserialized asNone
.The example shows that we deserialize
None
despite serializingSome
. I'd expect to read the value that I stored.The text was updated successfully, but these errors were encountered: