-
Notifications
You must be signed in to change notification settings - Fork 2
/
resolvers.go
93 lines (76 loc) · 1.7 KB
/
resolvers.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
package submodule
import (
"fmt"
"reflect"
)
func isInEmbedded(t reflect.Type) bool {
if t.Kind() != reflect.Struct {
return false
}
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
if f.Type == inType {
return true
}
}
return false
}
func isSelf(t reflect.Type) bool {
return t.AssignableTo(selfType)
}
func resolveEmbedded(as Scope, t reflect.Type, v reflect.Value, dependencies []Retrievable) (reflect.Value, error) {
var pt reflect.Type
var pv reflect.Value
store := GetStore()
if as != nil {
store = as
}
if t.Kind() == reflect.Pointer {
pv = reflect.Indirect(v)
pt = t.Elem()
} else {
pv = reflect.Indirect(v)
pt = t
}
for i := 0; i < pt.NumField(); i++ {
f := pt.Field(i)
if f.Anonymous {
continue
}
if !f.IsExported() {
return pv, fmt.Errorf("unable to resolve unexported field: %s, field is not exported", f.Name)
}
value, err := resolveType(store, f.Type, dependencies)
if err != nil {
return pv, fmt.Errorf("unable to resolve embedded %s\n%w", t.String(), err)
}
pv.Field(i).Set(value)
}
if t.Kind() == reflect.Pointer {
return pv.Addr(), nil
}
return pv, nil
}
func resolveType(store Scope, t reflect.Type, dependencies []Retrievable) (v reflect.Value, e error) {
if isInEmbedded(t) {
var sv reflect.Value
if t.Kind() == reflect.Pointer {
sv = reflect.New(t.Elem())
} else {
sv = reflect.New(t)
}
v, e = resolveEmbedded(store, t, sv, dependencies)
return
}
for _, d := range dependencies {
if d.canResolve(t) {
vv, err := d.retrieve(store)
if err != nil {
return v, err
}
v = reflect.ValueOf(vv)
return
}
}
return v, fmt.Errorf("unable to resolve dependency for type: %s", t.String())
}