How to handle Avro Unions
mainAvro unions can be handled in three ways in Go:
map[string]any: If the union value isnil, anilmap is used. For non-nil values, a single key is decoded where the key is the Avro type name or schema full name.*T(Nullable Unions): For unions like["null", "string"], you can use a pointer*TwhereTmatches the non-null type. Slices can also be used directly.UnionConverterinterface: For type-safe handling, implement theUnionConverterinterface. Note: The implementation must use pointer receivers.
type UnionConverter interface {
FromAny(payload any) error
ToAny() (any, error)
}any(interface{}): You can provide an interface, but named types, maps, and slices must be registered using theRegisterfunction. For arrays and maps, the schema type/name is appended as a postfix (e.g.,"map:string").
type UnionConverter interface {
// FromAny payload decode into any of the mentioned types in the Union.
FromAny(payload any) error
// ToAny from the Union struct
ToAny() (any, error)
}
// Example implementation
type UnionRecord struct {
Int *int
Test *TestRecord
}
func (u *UnionRecord) ToAny() (any, error) {
if u.Int != nil {
return u.Int, nil
} else if u.Test != nil {
return u.Test, nil
}
return nil, errors.New("no value to encode")
}
func (u *UnionRecord) FromAny(payload any) error {
switch t := payload.(type) {
case int:
u.Int = &t
case TestRecord:
u.Test = &t
default:
return errors.New("unknown type during decode of union")
}
return nil
}