...
1 package pgtype
2
3 import (
4 "reflect"
5 )
6
7 func NullAssignTo(dst any) error {
8 dstPtr := reflect.ValueOf(dst)
9
10
11 if dstPtr.Kind() != reflect.Ptr {
12 return &nullAssignmentError{dst: dst}
13 }
14
15 dstVal := dstPtr.Elem()
16
17 switch dstVal.Kind() {
18 case reflect.Ptr, reflect.Slice, reflect.Map:
19 dstVal.Set(reflect.Zero(dstVal.Type()))
20 return nil
21 }
22
23 return &nullAssignmentError{dst: dst}
24 }
25
26 var kindTypes map[reflect.Kind]reflect.Type
27
28 func toInterface(dst reflect.Value, t reflect.Type) (any, bool) {
29 nextDst := dst.Convert(t)
30 return nextDst.Interface(), dst.Type() != nextDst.Type()
31 }
32
33
34
35
36
37
38
39
40 func GetAssignToDstType(dst any) (any, bool) {
41 dstPtr := reflect.ValueOf(dst)
42
43
44 if dstPtr.Kind() != reflect.Ptr {
45 return nil, false
46 }
47
48 dstVal := dstPtr.Elem()
49
50
51 if dstVal.Kind() == reflect.Ptr {
52 dstVal.Set(reflect.New(dstVal.Type().Elem()))
53 return dstVal.Interface(), true
54 }
55
56
57 if baseValType, ok := kindTypes[dstVal.Kind()]; ok {
58 return toInterface(dstPtr, reflect.PtrTo(baseValType))
59 }
60
61 if dstVal.Kind() == reflect.Slice {
62 if baseElemType, ok := kindTypes[dstVal.Type().Elem().Kind()]; ok {
63 return toInterface(dstPtr, reflect.PtrTo(reflect.SliceOf(baseElemType)))
64 }
65 }
66
67 if dstVal.Kind() == reflect.Array {
68 if baseElemType, ok := kindTypes[dstVal.Type().Elem().Kind()]; ok {
69 return toInterface(dstPtr, reflect.PtrTo(reflect.ArrayOf(dstVal.Len(), baseElemType)))
70 }
71 }
72
73 if dstVal.Kind() == reflect.Struct {
74 if dstVal.Type().NumField() == 1 && dstVal.Type().Field(0).Anonymous {
75 dstPtr = dstVal.Field(0).Addr()
76 nested := dstVal.Type().Field(0).Type
77 if nested.Kind() == reflect.Array {
78 if baseElemType, ok := kindTypes[nested.Elem().Kind()]; ok {
79 return toInterface(dstPtr, reflect.PtrTo(reflect.ArrayOf(nested.Len(), baseElemType)))
80 }
81 }
82 if _, ok := kindTypes[nested.Kind()]; ok && dstPtr.CanInterface() {
83 return dstPtr.Interface(), true
84 }
85 }
86 }
87
88 return nil, false
89 }
90
91 func init() {
92 kindTypes = map[reflect.Kind]reflect.Type{
93 reflect.Bool: reflect.TypeOf(false),
94 reflect.Float32: reflect.TypeOf(float32(0)),
95 reflect.Float64: reflect.TypeOf(float64(0)),
96 reflect.Int: reflect.TypeOf(int(0)),
97 reflect.Int8: reflect.TypeOf(int8(0)),
98 reflect.Int16: reflect.TypeOf(int16(0)),
99 reflect.Int32: reflect.TypeOf(int32(0)),
100 reflect.Int64: reflect.TypeOf(int64(0)),
101 reflect.Uint: reflect.TypeOf(uint(0)),
102 reflect.Uint8: reflect.TypeOf(uint8(0)),
103 reflect.Uint16: reflect.TypeOf(uint16(0)),
104 reflect.Uint32: reflect.TypeOf(uint32(0)),
105 reflect.Uint64: reflect.TypeOf(uint64(0)),
106 reflect.String: reflect.TypeOf(""),
107 }
108 }
109
View as plain text