-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathprovider.go
More file actions
72 lines (60 loc) · 1.47 KB
/
provider.go
File metadata and controls
72 lines (60 loc) · 1.47 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
package gone
import "reflect"
type wrapProvider struct {
value any
hasParameter bool
t reflect.Type
}
func tryWrapGonerToProvider(goner any) *wrapProvider {
if goner == nil {
return nil
}
gonerType := reflect.TypeOf(goner)
if gonerType.Kind() != reflect.Ptr {
return nil
}
method, ok := gonerType.MethodByName("Provide")
if !ok {
return nil
}
ft := method.Type
hasParameter := ft.NumIn() == 2 && ft.In(1).Kind() == reflect.String
isValid := (ft.NumIn() == 1 || hasParameter) && ft.NumOut() == 2 && ft.Out(1).Implements(errType)
if !isValid {
return nil
}
return &wrapProvider{
value: goner,
hasParameter: hasParameter,
t: ft.Out(0),
}
}
func (p *wrapProvider) Provide(conf string) (any, error) {
if p.hasParameter {
results := reflect.ValueOf(p.value).MethodByName("Provide").Call([]reflect.Value{
reflect.ValueOf(conf),
})
if results[1].IsNil() {
return results[0].Interface(), nil
}
return nil, results[1].Interface().(error)
}
results := reflect.ValueOf(p.value).MethodByName("Provide").Call(nil)
if results[1].IsNil() {
return results[0].Interface(), nil
}
return nil, results[1].Interface().(error)
}
func (p *wrapProvider) Type() reflect.Type {
return p.t
}
func (p *wrapProvider) ProvideTypeCompatible(t reflect.Type) bool {
if p.t == t {
return true
}
if t.Kind() == reflect.Interface && p.t.Implements(t) {
return true
}
return false
}
var errType = reflect.TypeOf((*error)(nil)).Elem()