-
Notifications
You must be signed in to change notification settings - Fork 0
/
base_copier.go
103 lines (86 loc) · 2.48 KB
/
base_copier.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
package deepcopy
import (
"reflect"
)
// copier base interface defines Copy function
type copier interface {
Copy(dst, src reflect.Value) error
}
// nopCopier no-op copier
type nopCopier struct {
}
// Copy implementation of Copy function for no-op copier
func (c *nopCopier) Copy(dst, src reflect.Value) error {
return nil
}
// value2PtrCopier data structure of copier that copies from a value to a pointer
type value2PtrCopier struct {
ctx *Context
copier copier
}
// Copy implementation of Copy function for value-to-pointer copier
func (c *value2PtrCopier) Copy(dst, src reflect.Value) error {
if dst.IsNil() {
dst.Set(reflect.New(dst.Type().Elem()))
}
dst = dst.Elem()
return c.copier.Copy(dst, src)
}
func (c *value2PtrCopier) init(dstType, srcType reflect.Type) (err error) {
c.copier, err = buildCopier(c.ctx, dstType.Elem(), srcType)
return
}
// ptr2ValueCopier data structure of copier that copies from a pointer to a value
type ptr2ValueCopier struct {
ctx *Context
copier copier
}
// Copy implementation of Copy function for pointer-to-value copier
func (c *ptr2ValueCopier) Copy(dst, src reflect.Value) error {
src = src.Elem()
if !src.IsValid() {
dst.Set(reflect.Zero(dst.Type())) // NOTE: Go1.18 has no SetZero
return nil
}
return c.copier.Copy(dst, src)
}
func (c *ptr2ValueCopier) init(dstType, srcType reflect.Type) (err error) {
c.copier, err = buildCopier(c.ctx, dstType, srcType.Elem())
return
}
// ptr2PtrCopier data structure of copier that copies from a pointer to a pointer
type ptr2PtrCopier struct {
ctx *Context
copier copier
}
// Copy implementation of Copy function for pointer-to-pointer copier
func (c *ptr2PtrCopier) Copy(dst, src reflect.Value) error {
src = src.Elem()
if !src.IsValid() {
dst.Set(reflect.Zero(dst.Type())) // NOTE: Go1.18 has no SetZero
return nil
}
if dst.IsNil() {
dst.Set(reflect.New(dst.Type().Elem()))
}
dst = dst.Elem()
return c.copier.Copy(dst, src)
}
func (c *ptr2PtrCopier) init(dstType, srcType reflect.Type) (err error) {
c.copier, err = buildCopier(c.ctx, dstType.Elem(), srcType.Elem())
return
}
// directCopier copier that does copying by assigning `src` value to `dst` directly
type directCopier struct {
}
func (c *directCopier) Copy(dst, src reflect.Value) error {
dst.Set(src)
return nil
}
// convCopier copier that does copying with converting `src` value to `dst` type
type convCopier struct {
}
func (c *convCopier) Copy(dst, src reflect.Value) error {
dst.Set(src.Convert(dst.Type()))
return nil
}