cbor icon indicating copy to clipboard operation
cbor copied to clipboard

Enums inside flattened structs are serialised improperly

Open anna-is-cute opened this issue 6 years ago • 4 comments

See here for a minimal implementation of this bug. cargo run is sufficient to show the issue (it will panic).

When an enum inside of a flattened struct is serialised, it is serialised as an integer. This makes the serialisation fail round-trip: it cannot be deserialised after being serialised.

Also surprising to me is that, even though I'm using to_vec_packed, all the field names are still strings. Is this me misunderstanding how packed encoding should work?

anna-is-cute avatar Aug 30 '19 20:08 anna-is-cute

Also surprising to me is that, even though I'm using to_vec_packed, all the field names are still strings. Is this me misunderstanding how packed encoding should work?

That's odd.

pyfisch avatar Sep 02 '19 16:09 pyfisch

I've added a test to see if the names of struct are serialized if packed encoding is selected. The names are not serialized if packed encoding selected unless the flatten attribute is used.

Normally if a struct is serialized both the field indizes and the field names are sent to serde-cbor. But if the flatten attribute is present only the field names are forwarded. Therefore I think it is not possible to use flatten together with packed encoding.

If you have a look at the serde docs you'll see that it is stated that only named fields are supported.

I consider this to be a wontfix issue, but if you really want to use indizes and flatten a struct you can always write your own deserializer/serializer pair.

Diagnostic output:

flatten+packed: http://cbor.me/?bytes=81(BF(68(706C6174666F726D)-00-FF)) flatten: http://cbor.me/?bytes=81(BF(68(706C6174666F726D)-65(416D643634)-FF)) Curiously packed serialization round-trips if I replace the platform enum with an integer type (but fields are still named).

pyfisch avatar Sep 07 '19 11:09 pyfisch

I see! Good to know why that happens.

The main point of this issue is that the enum in my example does not serialise correctly, though. It serialises as an integer and not a string.

Edit: Oh, I see that your examples show using the enum with non-packed and packed. So do you see fixing the enum serialisation in flattened structs to be wontfix?

anna-is-cute avatar Sep 07 '19 17:09 anna-is-cute

The main point of this issue is that the enum in my example does not serialise correctly, though. It serialises as an integer and not a string.

The enum should serialize as an integer (because of packed encoding). As I understand it the flatten attribute should only affect the attribute names. To me the question is rather why the serialization does not round-trip even though the only difference between flatten+packed and just flatten is that the contained enum is serialized differently.

pyfisch avatar Sep 08 '19 08:09 pyfisch