This repository was archived by the owner on Sep 19, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathinject.go
84 lines (68 loc) · 2.27 KB
/
inject.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
package angularjs
import (
"reflect"
"github.com/gopherjs/gopherjs/js"
"github.com/pkg/errors"
)
var (
injectMap = make(map[reflect.Type]*Inject)
)
// Inject represents a resource that can be injected into an controller/directive/route-resolve func
type Inject struct {
f func(obj *js.Object) reflect.Value
angularName string
}
// RegisterResource registers a resource that can be injected
func RegisterResource(resourceType reflect.Type, angularName string, f func(obj *js.Object) reflect.Value) {
injectMap[resourceType] = &Inject{
f: f,
angularName: angularName,
}
}
// GetResource returns the resource for a given reflect.Type
func GetResource(resourceType reflect.Type) *Inject {
return injectMap[resourceType]
}
// MakeFuncInjectable returns a func that transforms *js.Object's to
// the corresponding go types.
func MakeFuncInjectable(f interface{}) (jsFunc js.S, err error) {
angularParamNames := make(js.S, 0)
transFormFuncs := make([]func(obj *js.Object) reflect.Value, 0)
injects, callable, err := GetFuncInjectables(f)
if err != nil {
return nil, err
}
for _, i := range injects {
angularParamNames = append(angularParamNames, i.angularName)
transFormFuncs = append(transFormFuncs, i.f)
}
// we return an optional *js.Object here if the function returns it
return append(angularParamNames, func(objs ...*js.Object) *js.Object {
args := make([]reflect.Value, 0)
for i, obj := range objs {
args = append(args, transFormFuncs[i](obj))
}
ret := callable.Call(args)
if len(ret) == 0 {
return nil
}
return ret[0].Interface().(*js.Object)
}), nil
}
// GetFuncInjectables reads the function arguments and transforms them to *Inject resources.
// If an arguments is not found the returns an error.
func GetFuncInjectables(f interface{}) (injects []*Inject, callable reflect.Value, err error) {
callable = reflect.ValueOf(f)
if callable.Kind() != reflect.Func {
return nil, callable, errors.New("Only func's can be made injectable")
}
for i := 0; i < callable.Type().NumIn(); i++ {
arg := callable.Type().In(i)
if injector := GetResource(arg); injector != nil {
injects = append(injects, injector)
} else {
return nil, callable, errors.Errorf("no resource found for type: %v", arg)
}
}
return injects, callable, nil
}