[
https://issues.apache.org/jira/browse/AVRO-3646?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17656637#comment-17656637
]
Martin Tzvetanov Grigorov commented on AVRO-3646:
-------------------------------------------------
Serializing a Rust enum to Avro Value works now only if the enum variants are
unit, i.e. without values (tuple or struct).
The requested feature in this ticket is to support also the complex types of
variants and to be able to validate them with Avro schema.
Today Avro Schema::Enum is good enough to represent Rust Enum due to the
simplicity of unit variants (just a name, without any values).
But for tuple/struct variants we need more complex Avro schema! I came up with
a Union(Null, Record*). I.e. a Rust Enum can have at most one variant that
serializes to Avro Value::Null and any number of tuple/struct variants with
different types and/or number of parameters which will be mapped to Avro
Schema::Record.
The above is implemented and seems to work!
What is left is to preserve the support for the simple enums, i.e. Rust enum
with just unit variants that maps to Avro Schema::Enum.
I have an idea to use Serde's serialize_with attribute or maybe use serde_with
crate, so the user can hint apache_avro how to serialize any Rust enum to Avro
Value. I have to experiment and see whether my idea will work or not.
> Serialization / deserialization for enum with mixed variants (with and
> without data)
> ------------------------------------------------------------------------------------
>
> Key: AVRO-3646
> URL: https://issues.apache.org/jira/browse/AVRO-3646
> Project: Apache Avro
> Issue Type: Bug
> Components: rust
> Reporter: Lucas Javaudin
> Assignee: Martin Tzvetanov Grigorov
> Priority: Major
> Labels: pull-request-available, rust
> Time Spent: 5h
> Remaining Estimate: 0h
>
> Consider the following example of what I call an "enum with mixed variants":
> {code:java}
> enum MixedExternalEnum {
> Val1,
> Val2(f32),
> } {code}
> 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
> {code:java}
> Value::Record(vec![("a".to_owned(), Value::Enum(0, "Val1".to_owned()))])
> {code}
> while the serialized version of {{MixedExternalEnum::Val2(0.0)}} is
> {code:java}
> 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))),
> ),
> ]),
> )])
> {code}
> 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
> {code:java}
> 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)),
> ),
> ]),
> )])
> {code}
>
> 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...
--
This message was sent by Atlassian Jira
(v8.20.10#820010)