pyfisch/cbor

Enums inside flattened structs are serialised improperly

anna-is-cute opened this issue · 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?

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.

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).

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.