jamesmunns / postcard

A no_std + serde compatible message library for Rust
Apache License 2.0
788 stars 76 forks source link

[Bug] Postcard does not handle serde attribute skip_serializing_if properly #122

Closed tugtugtug closed 6 months ago

tugtugtug commented 6 months ago
#[test]
fn test_serialize_flow_context() {
    #[derive(PartialEq, Debug, Default, Deserialize, Serialize, Clone)]
    pub struct Test {
        /// The id of the policy the lookup matched on
        #[serde(default, rename = "pid", skip_serializing_if = "Option::is_none")]
        pub policy_id: Option<String>,
        /// The name of the policy the lookup matched on
        #[serde(default, rename = "pname", skip_serializing_if = "Option::is_none")]
        pub policy_name: Option<String>,
    }
    let binary = postcard::to_allocvec(&Test::default()).unwrap();
    let _: Test = postcard::from_bytes(binary.as_ref()).unwrap();
}

This fails, and if I remove the skip_serializing_if attributes from the fields, then it works.

jamesmunns commented 6 months ago

In general, postcard does not handle many of serde's attributes that only apply to self describing formats. See also #29.

Docs PRs welcome that make this more clear.

tugtugtug commented 6 months ago

@jamesmunns thanks for your comments, and I kinda agree that postcard may not support all attributes, that's fine. But is there anything postcard can do to ensure the consistency of the behaviour between its own serialization and the deserialization?

elrafoon commented 6 months ago

I just hit the same problem.

And it's much worse if the same type needs to be serializes/deserialized with postcard and some other serializer - json, cbor, ...

Then it may be not possible to just adjust serde attributes to the postcard's taste, because it would break formatting for other serializer (that i.e. must fullfil some json schema).

jamesmunns commented 6 months ago

@tugtugtug:

But is there anything postcard can do to ensure the consistency of the behaviour between its own serialization and the deserialization

I am not aware of any way to statically "notice" that round-trips will fail if you use any of the relevant serde attributes, nor am I aware of any way of preventing it in the first place.

If you find a way, I am very interested!

jamesmunns commented 6 months ago

I've opened https://github.com/jamesmunns/postcard/issues/125 to track this, please feel free to discuss there if you have potential solutions or ideas.