diff --git a/convert.go b/convert.go index 8ae599b9..7c8ff198 100644 --- a/convert.go +++ b/convert.go @@ -8,9 +8,11 @@ import ( "time" ) -const maxUint = ^uint(0) -const maxInt = int(maxUint >> 1) -const minInt = -maxInt - 1 +const ( + maxUint = ^uint(0) + maxInt = int(maxUint >> 1) + minInt = -maxInt - 1 +) // underlyingNumberType gets the underlying type that can be converted to Int2, Int4, Int8, Float4, or Float8 func underlyingNumberType(val interface{}) (interface{}, bool) { @@ -432,6 +434,23 @@ func GetAssignToDstType(dst interface{}) (interface{}, bool) { } } + if dstVal.Kind() == reflect.Struct { + if dstVal.Type().NumField() == 1 && dstVal.Type().Field(0).Anonymous { + dstPtr = dstVal.Field(0).Addr() + nested := dstVal.Type().Field(0).Type + if nested.Kind() == reflect.Array { + if baseElemType, ok := kindTypes[nested.Elem().Kind()]; ok { + baseArrayType := reflect.PtrTo(reflect.ArrayOf(nested.Len(), baseElemType)) + nextDst := dstPtr.Convert(baseArrayType) + return nextDst.Interface(), dstPtr.Type() != nextDst.Type() + } + } + if _, ok := kindTypes[nested.Kind()]; ok && dstPtr.CanInterface() { + return dstPtr.Interface(), true + } + } + } + return nil, false } diff --git a/uuid_test.go b/uuid_test.go index 8de5b9f6..5a93ea8d 100644 --- a/uuid_test.go +++ b/uuid_test.go @@ -16,6 +16,10 @@ func TestUUIDTranscode(t *testing.T) { }) } +type SomeUUIDWrapper struct { + SomeUUIDType +} + type SomeUUIDType [16]byte func TestUUIDSet(t *testing.T) { @@ -127,6 +131,20 @@ func TestUUIDAssignTo(t *testing.T) { } } + { + src := pgtype.UUID{Bytes: [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, Status: pgtype.Present} + var dst SomeUUIDWrapper + expected := [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} + + err := src.AssignTo(&dst) + if err != nil { + t.Error(err) + } + + if dst.SomeUUIDType != expected { + t.Errorf("expected %v to assign %v, but result was %v", src, expected, dst) + } + } } func TestUUID_MarshalJSON(t *testing.T) {