Skip to content

Commit

Permalink
feat: use generics to remove repetitive codecs (#269)
Browse files Browse the repository at this point in the history
  • Loading branch information
nrwiersma authored Jun 18, 2023
1 parent d0e80f0 commit 3abfe1e
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 90 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
go-version: [ 1.19, "1.20" ]
runs-on: ubuntu-latest
env:
GOLANGCI_LINT_VERSION: v1.52.2
GOLANGCI_LINT_VERSION: v1.53.3

steps:
- name: Install Go
Expand Down
1 change: 1 addition & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ linters:
- structcheck # deprecated
- varcheck # deprecated
- cyclop # duplicate of gocyclo
- depguard
- exhaustive
- exhaustruct
- forcetypeassert
Expand Down
120 changes: 31 additions & 89 deletions codec_native.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,43 +22,43 @@ func createDecoderOfNative(schema Schema, typ reflect2.Type) ValDecoder {
if schema.Type() != Int {
break
}
return &intCodec{}
return &intCodec[int]{}

case reflect.Int8:
if schema.Type() != Int {
break
}
return &int8Codec{}
return &intCodec[int8]{}

case reflect.Uint8:
if schema.Type() != Int {
break
}
return &uint8Codec{}
return &intCodec[uint8]{}

case reflect.Int16:
if schema.Type() != Int {
break
}
return &int16Codec{}
return &intCodec[int16]{}

case reflect.Uint16:
if schema.Type() != Int {
break
}
return &uint16Codec{}
return &intCodec[uint16]{}

case reflect.Int32:
if schema.Type() != Int {
break
}
return &int32Codec{}
return &intCodec[int32]{}

case reflect.Uint32:
if schema.Type() != Long {
break
}
return &uint32Codec{}
return &longCodec[uint32]{}

case reflect.Int64:
st := schema.Type()
Expand All @@ -71,7 +71,7 @@ func createDecoderOfNative(schema Schema, typ reflect2.Type) ValDecoder {
return &timeMicrosCodec{}

case st == Long:
return &int64Codec{}
return &longCodec[int64]{}

default:
break
Expand Down Expand Up @@ -157,46 +157,46 @@ func createEncoderOfNative(schema Schema, typ reflect2.Type) ValEncoder {
if schema.Type() != Int {
break
}
return &intCodec{}
return &intCodec[int]{}

case reflect.Int8:
if schema.Type() != Int {
break
}
return &int8Codec{}
return &intCodec[int8]{}

case reflect.Uint8:
if schema.Type() != Int {
break
}
return &uint8Codec{}
return &intCodec[uint8]{}

case reflect.Int16:
if schema.Type() != Int {
break
}
return &int16Codec{}
return &intCodec[int16]{}

case reflect.Uint16:
if schema.Type() != Int {
break
}
return &uint16Codec{}
return &intCodec[uint16]{}

case reflect.Int32:
switch schema.Type() {
case Long:
return &int32LongCodec{}
return &longCodec[int32]{}

case Int:
return &int32Codec{}
return &intCodec[int32]{}
}

case reflect.Uint32:
if schema.Type() != Long {
break
}
return &uint32Codec{}
return &longCodec[uint32]{}

case reflect.Int64:
st := schema.Type()
Expand All @@ -209,7 +209,7 @@ func createEncoderOfNative(schema Schema, typ reflect2.Type) ValEncoder {
return &timeMicrosCodec{}

case st == Long:
return &int64Codec{}
return &longCodec[int64]{}

default:
break
Expand Down Expand Up @@ -322,90 +322,32 @@ func (*boolCodec) Encode(ptr unsafe.Pointer, w *Writer) {
w.WriteBool(*((*bool)(ptr)))
}

type intCodec struct{}

func (*intCodec) Decode(ptr unsafe.Pointer, r *Reader) {
*((*int)(ptr)) = int(r.ReadInt())
}

func (*intCodec) Encode(ptr unsafe.Pointer, w *Writer) {
w.WriteInt(int32(*((*int)(ptr))))
}

type int8Codec struct{}

func (*int8Codec) Decode(ptr unsafe.Pointer, r *Reader) {
*((*int8)(ptr)) = int8(r.ReadInt())
}

func (*int8Codec) Encode(ptr unsafe.Pointer, w *Writer) {
w.WriteInt(int32(*((*int8)(ptr))))
type smallInt interface {
~int | ~int8 | ~int16 | ~int32 | ~uint | ~uint8 | ~uint16
}

type uint8Codec struct{}
type intCodec[T smallInt] struct{}

func (*uint8Codec) Decode(ptr unsafe.Pointer, r *Reader) {
*((*uint8)(ptr)) = uint8(r.ReadInt())
func (*intCodec[T]) Decode(ptr unsafe.Pointer, r *Reader) {
*((*T)(ptr)) = T(r.ReadInt())
}

func (*uint8Codec) Encode(ptr unsafe.Pointer, w *Writer) {
w.WriteInt(int32(*((*uint8)(ptr))))
func (*intCodec[T]) Encode(ptr unsafe.Pointer, w *Writer) {
w.WriteInt(int32(*((*T)(ptr))))
}

type int16Codec struct{}

func (*int16Codec) Decode(ptr unsafe.Pointer, r *Reader) {
*((*int16)(ptr)) = int16(r.ReadInt())
}

func (*int16Codec) Encode(ptr unsafe.Pointer, w *Writer) {
w.WriteInt(int32(*((*int16)(ptr))))
}

type uint16Codec struct{}

func (*uint16Codec) Decode(ptr unsafe.Pointer, r *Reader) {
*((*uint16)(ptr)) = uint16(r.ReadInt())
}

func (*uint16Codec) Encode(ptr unsafe.Pointer, w *Writer) {
w.WriteInt(int32(*((*uint16)(ptr))))
}

type int32Codec struct{}

func (*int32Codec) Decode(ptr unsafe.Pointer, r *Reader) {
*((*int32)(ptr)) = r.ReadInt()
}

func (*int32Codec) Encode(ptr unsafe.Pointer, w *Writer) {
w.WriteInt(*((*int32)(ptr)))
}

type uint32Codec struct{}

func (*uint32Codec) Decode(ptr unsafe.Pointer, r *Reader) {
*((*uint32)(ptr)) = uint32(r.ReadLong())
}

func (*uint32Codec) Encode(ptr unsafe.Pointer, w *Writer) {
w.WriteLong(int64(*((*uint32)(ptr))))
}

type int32LongCodec struct{}

func (*int32LongCodec) Encode(ptr unsafe.Pointer, w *Writer) {
w.WriteLong(int64(*((*int32)(ptr))))
type largeInt interface {
~int32 | ~uint32 | int64
}

type int64Codec struct{}
type longCodec[T largeInt] struct{}

func (*int64Codec) Decode(ptr unsafe.Pointer, r *Reader) {
*((*int64)(ptr)) = r.ReadLong()
func (*longCodec[T]) Decode(ptr unsafe.Pointer, r *Reader) {
*((*T)(ptr)) = T(r.ReadLong())
}

func (*int64Codec) Encode(ptr unsafe.Pointer, w *Writer) {
w.WriteLong(*((*int64)(ptr)))
func (*longCodec[T]) Encode(ptr unsafe.Pointer, w *Writer) {
w.WriteLong(int64(*((*T)(ptr))))
}

type float32Codec struct{}
Expand Down

0 comments on commit 3abfe1e

Please sign in to comment.