-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmorph.go
127 lines (112 loc) Β· 3.1 KB
/
morph.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package morph
import (
"reflect"
"unsafe"
)
// constants
const (
// arrIndexValue index for take out value from []interface{}
arrIndexValue = 1
// arrIndexType index for take out type from []interface{}
arrIndexType = 0
)
type Transformed struct {
From interface{}
}
// StructTransformed struct
type StructTransformed Transformed
// ProtocTransformed struct
type ProtocTransformed Transformed
func apply(to interface{}, copies map[string][]interface{}) {
b := reflect.ValueOf(to).Elem()
for k, v := range copies {
switch v[arrIndexType] {
case "bool":
b.FieldByName(k).SetBool(v[arrIndexValue].(bool))
case "string":
b.FieldByName(k).SetString(v[arrIndexValue].(string))
case "byte":
b.FieldByName(k).SetBytes(v[arrIndexValue].([]byte))
case "float32":
val := v[arrIndexValue].(float32)
b.FieldByName(k).SetFloat(float64(val))
case "float64":
val := v[arrIndexValue].(float64)
b.FieldByName(k).SetFloat(val)
case "int":
val := v[arrIndexValue].(int)
b.FieldByName(k).SetInt(int64(val))
case "int8":
val := v[arrIndexValue].(int8)
b.FieldByName(k).SetInt(int64(val))
case "int16":
val := v[arrIndexValue].(int16)
b.FieldByName(k).SetInt(int64(val))
case "int32":
val := v[arrIndexValue].(int32)
b.FieldByName(k).SetInt(int64(val))
case "int64":
val := v[arrIndexValue].(int64)
b.FieldByName(k).SetInt(val)
case "uint":
val := v[arrIndexValue].(uint)
b.FieldByName(k).SetUint(uint64(val))
case "uint8":
val := v[arrIndexValue].(uint8)
b.FieldByName(k).SetUint(uint64(val))
case "uint16":
val := v[arrIndexValue].(uint16)
b.FieldByName(k).SetUint(uint64(val))
case "uint32":
val := v[arrIndexValue].(uint32)
b.FieldByName(k).SetUint(uint64(val))
case "uint64":
val := v[arrIndexValue].(uint64)
b.FieldByName(k).SetUint(val)
case "uintptr":
val := v[arrIndexValue].(uintptr)
b.FieldByName(k).SetUint(uint64(val))
}
}
}
func Protoc(p interface{}) StructTransformed {
return StructTransformed{From: p}
}
func Struct(s interface{}) ProtocTransformed {
return ProtocTransformed{From: s}
}
func (t StructTransformed) Struct(to interface{}) {
e := reflect.ValueOf(t.From).Elem()
b := reflect.ValueOf(to).Elem()
valueCopied := map[string][]interface{}{}
for i := 0; i < e.NumField(); i++ {
ref := e.Field(i)
refIdentify := e.Type().Field(i)
varName := refIdentify.Name
if varName == "Id" {
varName = "ID"
}
if b.FieldByName(varName).CanSet() {
varType := ref.Type().Name()
unsafeReflect := reflect.NewAt(ref.Type(), unsafe.Pointer(ref.UnsafeAddr())).Elem().Interface()
varValue := unsafeReflect
valueCopied[varName] = []interface{}{varType, varValue}
}
}
apply(to, valueCopied)
}
func (t ProtocTransformed) Protoc(to interface{}) {
e := reflect.ValueOf(t.From).Elem()
valueCopied := map[string][]interface{}{}
for i := 0; i < e.NumField(); i++ {
ref := e.Type().Field(i)
varName := ref.Name
if varName == "ID" {
varName = "Id"
}
varType := ref.Type.Name()
varValue := e.Field(i).Interface()
valueCopied[varName] = []interface{}{varType, varValue}
}
apply(to, valueCopied)
}