-
Notifications
You must be signed in to change notification settings - Fork 101
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d68f799
commit 10b955d
Showing
5 changed files
with
212 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package avro | ||
|
||
import ( | ||
"reflect" | ||
|
||
"github.com/modern-go/reflect2" | ||
) | ||
|
||
func getCodecPromoter[T any](actual Type) *codecPromoter[T] { | ||
Check failure on line 9 in codec_promoter.go GitHub Actions / test (1.20)
|
||
if actual == "" { | ||
return nil | ||
} | ||
|
||
return &codecPromoter[T]{actual: actual} | ||
} | ||
|
||
type codecPromoter[T any] struct { | ||
Check failure on line 17 in codec_promoter.go GitHub Actions / test (1.20)
|
||
actual Type | ||
} | ||
|
||
func (p *codecPromoter[T]) promote(r *Reader) (t T) { | ||
Check failure on line 21 in codec_promoter.go GitHub Actions / test (1.20)
|
||
tt := reflect2.TypeOf(t) | ||
|
||
convert := func(typ reflect2.Type, obj any) (t T) { | ||
if !reflect.TypeOf(obj).ConvertibleTo(typ.Type1()) { | ||
r.ReportError("decode promotable", "unsupported type") | ||
// return zero value | ||
return t | ||
} | ||
return reflect.ValueOf(obj).Convert(typ.Type1()).Interface().(T) | ||
} | ||
|
||
switch p.actual { | ||
case Int: | ||
var obj int32 | ||
(&intCodec[int32]{}).Decode(reflect2.PtrOf(&obj), r) | ||
t = convert(tt, obj) | ||
|
||
case Long: | ||
var obj int64 | ||
(&longCodec[int64]{}).Decode(reflect2.PtrOf(&obj), r) | ||
t = convert(tt, obj) | ||
|
||
case Float: | ||
var obj float32 | ||
(&float32Codec{}).Decode(reflect2.PtrOf(&obj), r) | ||
t = convert(tt, obj) | ||
|
||
case String: | ||
var obj string | ||
(&stringCodec{}).Decode(reflect2.PtrOf(&obj), r) | ||
t = convert(tt, obj) | ||
|
||
case Bytes: | ||
var obj []byte | ||
(&bytesCodec{}).Decode(reflect2.PtrOf(&obj), r) | ||
t = convert(tt, obj) | ||
|
||
default: | ||
r.ReportError("decode promotable", "unsupported actual type") | ||
} | ||
|
||
return t | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package avro | ||
|
||
import ( | ||
"reflect" | ||
) | ||
|
||
type ReaderPromoter interface { | ||
Check warning on line 7 in reader_promoter.go GitHub Actions / test (1.20)
|
||
ReadLong() int64 | ||
ReadFloat() float32 | ||
ReadDouble() float64 | ||
ReadString() string | ||
ReadBytes() []byte | ||
} | ||
|
||
type readerPromoter struct { | ||
actual, current Type | ||
r *Reader | ||
} | ||
|
||
var _ ReaderPromoter = &readerPromoter{} | ||
|
||
var promotedInvalid = struct{}{} | ||
|
||
func (p *readerPromoter) readActual() any { | ||
switch p.actual { | ||
case Int: | ||
return p.r.ReadInt() | ||
|
||
case Long: | ||
return p.r.ReadLong() | ||
|
||
case Float: | ||
return p.r.ReadFloat() | ||
|
||
case String: | ||
return p.r.ReadString() | ||
|
||
case Bytes: | ||
return p.r.ReadBytes() | ||
|
||
default: | ||
p.r.ReportError("decode promotable", "unsupported actual type") | ||
return promotedInvalid | ||
} | ||
} | ||
|
||
func (p *readerPromoter) ReadLong() int64 { | ||
if v := p.readActual(); v != promotedInvalid { | ||
return p.promote(v, p.current).(int64) | ||
} | ||
|
||
return 0 | ||
} | ||
|
||
func (p *readerPromoter) ReadFloat() float32 { | ||
if v := p.readActual(); v != promotedInvalid { | ||
return p.promote(v, p.current).(float32) | ||
} | ||
|
||
return 0 | ||
} | ||
|
||
func (p *readerPromoter) ReadDouble() float64 { | ||
if v := p.readActual(); v != promotedInvalid { | ||
return p.promote(v, p.current).(float64) | ||
} | ||
|
||
return 0 | ||
} | ||
|
||
func (p *readerPromoter) ReadString() string { | ||
if v := p.readActual(); v != promotedInvalid { | ||
return p.promote(v, p.current).(string) | ||
} | ||
|
||
return "" | ||
} | ||
|
||
func (p *readerPromoter) ReadBytes() []byte { | ||
if v := p.readActual(); v != promotedInvalid { | ||
return p.promote(v, p.current).([]byte) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (p *readerPromoter) promote(obj any, st Type) (t any) { | ||
switch st { | ||
case Long: | ||
return int64(reflect.ValueOf(obj).Int()) | ||
Check failure on line 90 in reader_promoter.go GitHub Actions / test (1.20)
|
||
case Float: | ||
return float32(reflect.ValueOf(obj).Int()) | ||
case Double: | ||
return float64(reflect.ValueOf(obj).Float()) | ||
Check failure on line 94 in reader_promoter.go GitHub Actions / test (1.20)
|
||
case String: | ||
return string(reflect.ValueOf(obj).Bytes()) | ||
case Bytes: | ||
return []byte(reflect.ValueOf(obj).String()) | ||
} | ||
|
||
return obj | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters