-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconvert.go
More file actions
118 lines (103 loc) · 3.33 KB
/
convert.go
File metadata and controls
118 lines (103 loc) · 3.33 KB
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
package protopatch
import "reflect"
// func (v *messageContainer) Convert(to any) (any, error) {
// if reflect.TypeOf(v.msg.Interface()) == reflect.TypeOf(to) {
// return v.msg.Interface(), nil
// }
// m, mOk := to.(proto.Message)
// pr, prOk := to.(protoreflect.Message)
// if !mOk && prOk {
// return nil, errors.New("cannot convert")
// }
// if mOk {
// pr = m.ProtoReflect()
// }
// if v.msg.Descriptor() != pr.Descriptor() {
// return nil, errors.New("cannot convert")
// }
// return v.msg.Interface(), nil
// }
// func (v *messageFieldValue) Convert(to any) (any, error) {
// if reflect.TypeOf(v.msg.Interface()) == reflect.TypeOf(to) {
// return v.msg.Interface(), nil
// }
// m, mOk := to.(proto.Message)
// pr, prOk := to.(protoreflect.Message)
// if !mOk && prOk {
// return nil, errors.New("cannot convert")
// }
// if mOk {
// pr = m.ProtoReflect()
// }
// if v.msg.Descriptor() != pr.Descriptor() {
// return nil, errors.New("cannot convert")
// }
// return v.msg.Interface(), nil
// }
// func (v *listContainer) Convert(to any) (any, error) {
// if i := v.Interface(); reflect.TypeOf(i) == reflect.TypeOf(to) {
// return i, nil
// }
// return nil, errors.New("cannot convert")
// }
// func (v *listElementValue) Convert(to any) (any, error) {
// if i := v.Interface(); reflect.TypeOf(i) == reflect.TypeOf(to) {
// return i, nil
// }
// return nil, errors.New("cannot convert")
// }
// func (v *mapContainer) Convert(to any) (any, error) {
// if i := v.Interface(); reflect.TypeOf(i) == reflect.TypeOf(to) {
// return i, nil
// }
// return nil, errors.New("cannot convert")
// }
// func (v *mapElementValue) Convert(to any) (any, error) {
// if i := v.Interface(); reflect.TypeOf(i) == reflect.TypeOf(to) {
// return i, nil
// }
// return nil, errors.New("cannot convert")
// }
// func (v *scalarValue) Convert(to any) (any, error) {
// if i := v.Interface(); reflect.TypeOf(i) == reflect.TypeOf(to) {
// return i, nil
// }
// return nil, errors.New("cannot convert")
// }
// IdentityConverter converts the provided value to itself ensuring that provided types match. It returns ErrNoConversionDefined error for mismatched types.
func IdentityConverter(to, from any) (any, error) {
toVal, fromVal := reflect.ValueOf(to), reflect.ValueOf(from)
// proto.Message, scalars, go types
if areValueTypesMatch(toVal, fromVal) {
return from, nil
}
// List to List
toList, toListOk := to.(List)
fromList, fromListOk := from.(List)
if toListOk && fromListOk && areProtoFieldMatch(toList.ParentFieldDescriptor(), fromList.ParentFieldDescriptor()) {
return from, nil
}
// slice to List
if toListOk && isValueTypeMatchesProtoField(toList.ParentFieldDescriptor(), fromVal) {
return from, nil
}
// List to slice
if fromListOk && isValueTypeMatchesProtoField(fromList.ParentFieldDescriptor(), toVal) {
return from, nil
}
// Map to Map
toMap, toMapOk := to.(Map)
fromMap, fromMapOk := from.(Map)
if toMapOk && fromMapOk && areProtoFieldMatch(toMap.ParentFieldDescriptor(), fromMap.ParentFieldDescriptor()) {
return from, nil
}
// map to Map
if toMapOk && isValueTypeMatchesProtoField(toMap.ParentFieldDescriptor(), fromVal) {
return from, nil
}
// Map to map
if fromMapOk && isValueTypeMatchesProtoField(fromMap.ParentFieldDescriptor(), toVal) {
return from, nil
}
return nil, ErrNoConversionDefined
}