-
Notifications
You must be signed in to change notification settings - Fork 95
/
codec_generic.go
131 lines (122 loc) · 2.62 KB
/
codec_generic.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package avro
import (
"errors"
"math/big"
"time"
"github.com/modern-go/reflect2"
)
func genericDecode(typ reflect2.Type, dec ValDecoder, r *Reader) any {
ptr := typ.UnsafeNew()
dec.Decode(ptr, r)
if r.Error != nil {
return nil
}
obj := typ.UnsafeIndirect(ptr)
if reflect2.IsNil(obj) {
return nil
}
return obj
}
func genericReceiver(schema Schema) (reflect2.Type, error) {
if schema.Type() == Ref {
schema = schema.(*RefSchema).Schema()
}
var ls LogicalSchema
lts, ok := schema.(LogicalTypeSchema)
if ok {
ls = lts.Logical()
}
schemaName := string(schema.Type())
if ls != nil {
schemaName += "." + string(ls.Type())
}
switch schema.Type() {
case Boolean:
var v bool
return reflect2.TypeOf(v), nil
case Int:
if ls != nil {
switch ls.Type() {
case Date:
var v time.Time
return reflect2.TypeOf(v), nil
case TimeMillis:
var v time.Duration
return reflect2.TypeOf(v), nil
}
}
var v int
return reflect2.TypeOf(v), nil
case Long:
if ls != nil {
switch ls.Type() {
case TimeMicros:
var v time.Duration
return reflect2.TypeOf(v), nil
case TimestampMillis:
var v time.Time
return reflect2.TypeOf(v), nil
case TimestampMicros:
var v time.Time
return reflect2.TypeOf(v), nil
case LocalTimestampMillis:
var v time.Time
return reflect2.TypeOf(v), nil
case LocalTimestampMicros:
var v time.Time
return reflect2.TypeOf(v), nil
}
}
var v int64
return reflect2.TypeOf(v), nil
case Float:
var v float32
return reflect2.TypeOf(v), nil
case Double:
var v float64
return reflect2.TypeOf(v), nil
case String:
var v string
return reflect2.TypeOf(v), nil
case Bytes:
if ls != nil && ls.Type() == Decimal {
var v *big.Rat
return reflect2.TypeOf(v), nil
}
var v []byte
return reflect2.TypeOf(v), nil
case Record:
var v map[string]any
return reflect2.TypeOf(v), nil
case Enum:
var v string
return reflect2.TypeOf(v), nil
case Array:
v := make([]any, 0)
return reflect2.TypeOf(v), nil
case Map:
var v map[string]any
return reflect2.TypeOf(v), nil
case Union:
var v map[string]any
return reflect2.TypeOf(v), nil
case Fixed:
fixed := schema.(*FixedSchema)
ls := fixed.Logical()
if ls != nil {
switch ls.Type() {
case Duration:
var v LogicalDuration
return reflect2.TypeOf(v), nil
case Decimal:
var v *big.Rat
return reflect2.TypeOf(v), nil
}
}
v := byteSliceToArray(make([]byte, fixed.Size()), fixed.Size())
return reflect2.TypeOf(v), nil
default:
// This should not be possible.
return nil, errors.New("dynamic receiver not found for schema " + schemaName)
}
}