-
Notifications
You must be signed in to change notification settings - Fork 48
Support flattening Option<T> into the UnionSchema of T #517
Description
Original issues #449 and #458 by @PookieBuns
Currently the SchemaAware(De)Serializer implementations only support one representation of Option<T>: ["null", T::get_schema()] (order of null and T does not matter). This means that the following schema:
[
"null",
"int",
"string"
]can only map to the following enum:
enum Example {
Null,
Int(i32),
String(String),
}It is requested that the following Option would also match this schema:
enum Example {
Int(i32),
String(String),
}
Option<Example>This would require the following changes to the serializer:
- In
serialize_someandserialize_none: Only require that the current schema is aSchema::Unionwith aSchema::Nullvariant - In
serialize_somethere are two cases to keep in mind:
- If there are only two variants, serialize using the current implementation.
- If there are more variants, serialize
Tusing the current union schema but provide a flag to the serializer that thenullvariant cannot be used. It would be preferable to modify the union schema/create a new union schema so that thenullvariant does not exist, but as we need a reference to the schema that would mean using aCow<Schema>everywhere.
- In
get_resolved_union_variantthe logic needs to be modified to correct the index:
- If the index is before the
nullvariant, it can be used as is - If the index is at or after the
nullvariant, the index needs to be incremented by one
UnionSerializerwould also need to be changed to ignore the null variant when the flag is set
This would require the following changes to the deserializer:
- In
deserialize_option:
- Only require that the current schema is a
Schema::Unionwith aSchema::Nullvariant - If a
nullis read, then the current logic can be used - Otherwise, store the index that was read and
visit_somewith the current deserializer
- In
with_unionreading the index must be skipped if the index is already set. - In
deserialize_enumtheUnionEnumDeserializermust be provided with the stored index - In
UnionEnumDeserializer::variant_seedthe stored index must be used if available
This would require the AvroSchemaComponent implementation for Option<T> to only panic if T::get_schema is a union with a Schema::Null variant, otherwise modify that schema to include Schema::Null.
There is probably more changes needed, but this is what I can think of right now.