Details
-
Bug
-
Status: Open
-
Major
-
Resolution: Unresolved
-
None
-
None
Description
Consider the following example of what I call an "enum with mixed variants":
enum MixedExternalEnum {
Val1,
Val2(f32),
}
For the two variants, this enum can be properly serialized to and deserialized from a types::Value (using ser::to_value and de::from_value). The problem is that the way they are represented as a types::Value cannot be represented using an Avro Schema.
The serialized version of MixedExternalEnum::Val1 is
Value::Record(vec![("a".to_owned(), Value::Enum(0, "Val1".to_owned()))])
while the serialized version of MixedExternalEnum::Val2(0.0) is
Value::Record(vec![( "a".to_owned(), Value::Record(vec![ ("type".to_owned(), Value::Enum(1, "Val2".to_owned())), ( "value".to_owned(), Value::Union(1, Box::new(Value::Float(0.0))), ), ]), )])
As far as I know, there is no Avro Schema compatible with both possible values.
One solution I can think of is to change the serialization of MixedExternalEnum::Val1 to
Value::Record(vec![( "a".to_owned(), Value::Record(vec![ ("type".to_owned(), Value::Enum(0, "Val1".to_owned())), ( "value".to_owned(), Value::Union(0, Box::new(Value::Null)), ), ]), )])
A workaround is to replace Val1 by Val1(()) in the enum definition (see AVRO-3645) but this can have undesirable effects for other parts of the code.
Then, it's another story for adjacently tagged, internally tagged and untagged enum...