Skip to content
This repository was archived by the owner on Jan 18, 2026. It is now read-only.

Commit 933e657

Browse files
authored
IPC Prep (#15)
1 parent f56072d commit 933e657

29 files changed

+1909
-487
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,11 @@ type name, or scheam full name in the case of a named schema (enum, fixed or rec
9191
* ***T:** This is allowed in a "nullable" union. A nullable union is defined as a two schema union,
9292
with the first being `null` (ie. `["null", "string"]`), in this case a `*T` is allowed,
9393
with `T` matching the conversion table above.
94-
* **avro.UnionType:** A `struct` in implementing `avro.UnionType` can be provided, allowing for
95-
strong type encoding. An example can be found in the [godoc](https://godoc.org/github.com/hamba/avro).
94+
* **interface{}:** An `interface` can be provided and the type or name resolved. Primitive types
95+
are pre-registered, but named types, maps and slices will need to be registered with the `Register` function. In the
96+
case of arrays and maps the enclosed schema type or name is postfix to the type
97+
with a `:` separator, e.g `"map:string"`. If any type cannot be resolved the map type above is used unless
98+
`Config.UnionResolutionError` is set to `true` in which case an error is returned.
9699

97100
## Benchmark
98101

avro.go

Lines changed: 0 additions & 9 deletions
This file was deleted.

bench_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ func BenchmarkSuperheroGenericDecode(b *testing.B) {
112112
b.ReportAllocs()
113113
b.ResetTimer()
114114
for i := 0; i < b.N; i++ {
115-
m := map[string]interface{}{}
115+
var m interface{}
116116
_ = avro.Unmarshal(schema, data, &m)
117117
}
118118
}

codec.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"github.com/modern-go/reflect2"
99
)
1010

11+
type null struct{}
12+
1113
// ValDecoder represents an internal value decoder.
1214
//
1315
// You should never use ValDecoder directly.
@@ -72,8 +74,8 @@ func (c *frozenConfig) DecoderOf(schema Schema, typ reflect2.Type) ValDecoder {
7274
}
7375

7476
func decoderOfType(cfg *frozenConfig, schema Schema, typ reflect2.Type) ValDecoder {
75-
// Handle eface case
76-
if typ.Kind() == reflect.Interface {
77+
// Handle eface case when it isnt a union
78+
if typ.Kind() == reflect.Interface && schema.Type() != Union {
7779
if _, ok := typ.(*reflect2.UnsafeIFaceType); !ok {
7880
return &efaceDecoder{schema: schema}
7981
}
@@ -111,6 +113,10 @@ func decoderOfType(cfg *frozenConfig, schema Schema, typ reflect2.Type) ValDecod
111113
}
112114

113115
func (c *frozenConfig) EncoderOf(schema Schema, typ reflect2.Type) ValEncoder {
116+
if typ == nil {
117+
typ = reflect2.TypeOf((*null)(nil))
118+
}
119+
114120
rtype := typ.RType()
115121
encoder := c.getEncoderFromCache(schema.Fingerprint(), rtype)
116122
if encoder != nil {
@@ -139,7 +145,7 @@ func encoderOfType(cfg *frozenConfig, schema Schema, typ reflect2.Type) ValEncod
139145
}
140146

141147
switch schema.Type() {
142-
case String, Bytes, Int, Long, Float, Double, Boolean:
148+
case String, Bytes, Int, Long, Float, Double, Boolean, Null:
143149
return createEncoderOfNative(schema, typ)
144150

145151
case Record:

codec_native.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,17 @@ func createEncoderOfNative(schema Schema, typ reflect2.Type) ValEncoder {
137137
return &bytesCodec{sliceType: typ.(*reflect2.UnsafeSliceType)}
138138
}
139139

140+
if schema.Type() == Null {
141+
return &nullCodec{}
142+
}
143+
140144
return &errorEncoder{err: fmt.Errorf("avro: %s is unsupported for Avro %s", typ.String(), schema.Type())}
141145
}
142146

147+
type nullCodec struct{}
148+
149+
func (*nullCodec) Encode(ptr unsafe.Pointer, w *Writer) {}
150+
143151
type boolCodec struct{}
144152

145153
func (*boolCodec) Decode(ptr unsafe.Pointer, r *Reader) {

codec_record.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,16 +119,16 @@ func encoderOfStruct(cfg *frozenConfig, schema Schema, typ reflect2.Type) ValEnc
119119
sf := structDesc.Fields.Get(field.Name())
120120

121121
if sf == nil {
122-
if field.Default() == nil {
123-
if field.Type().Type() == Null {
124-
// We write nothing in a Null case, just skip it
125-
continue
126-
}
127-
122+
if !field.HasDefault() {
128123
// In all other cases, this is a required field
129124
return &errorEncoder{err: fmt.Errorf("avro: record %s is missing required field %s", rec.FullName(), field.Name())}
130125
}
131126

127+
if field.Default() == nil {
128+
// We write nothing in a Null case, just skip it
129+
continue
130+
}
131+
132132
defaultType := reflect2.TypeOf(field.Default())
133133
fields = append(fields, &structFieldEncoder{
134134
defaultPtr: reflect2.PtrOf(field.Default()),
@@ -234,7 +234,7 @@ func encoderOfRecord(cfg *frozenConfig, schema Schema, typ reflect2.Type) ValEnc
234234
for i, field := range rec.Fields() {
235235
fields[i] = mapEncoderField{
236236
name: field.Name(),
237-
hasDef: field.Default() != nil || field.Type().Type() == Null,
237+
hasDef: field.HasDefault(),
238238
def: field.Default(),
239239
encoder: encoderOfType(cfg, field.Type(), mapType.Elem()),
240240
}

codec_skip.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ type unionSkipDecoder struct {
203203
}
204204

205205
func (d *unionSkipDecoder) Decode(ptr unsafe.Pointer, r *Reader) {
206-
resSchema := getUnionSchema(d.schema, r)
206+
_, resSchema := getUnionSchema(d.schema, r)
207207
if resSchema == nil {
208208
return
209209
}

0 commit comments

Comments
 (0)