-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathutils.go
More file actions
53 lines (42 loc) · 1.42 KB
/
utils.go
File metadata and controls
53 lines (42 loc) · 1.42 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
package fire
import (
"fmt"
"reflect"
"github.com/256dpi/fire/coal"
)
// P is a shorthand to look up the specified property method on the provided
// model. It will return a function that can be used to evaluate the property.
func P(model coal.Model, name string) func(coal.Model) (interface{}, error) {
// get meta
meta := coal.GetMeta(model)
// get pointer type
ptrType := reflect.PtrTo(meta.Type)
// get method
method, ok := ptrType.MethodByName(name)
if !ok {
panic(fmt.Sprintf(`fire: missing property method "%s" for model "%s"`, name, meta.Name))
}
// check parameters and return values
if method.Type.NumIn() != 1 || method.Type.NumOut() < 1 || method.Type.NumOut() > 2 {
panic(fmt.Sprintf(`fire: expected property method "%s" for model "%s" to have no parameters and one or two return values`, name, meta.Name))
}
// check second return value
if method.Type.NumOut() == 2 && method.Type.Out(1).String() != "error" {
panic(fmt.Sprintf(`fire: expected second return value of property method "%s" for model "%s" to be of type error`, name, meta.Name))
}
return func(model coal.Model) (interface{}, error) {
// prepare input
input := []reflect.Value{reflect.ValueOf(model)}
// call method
out := method.Func.Call(input)
// check error
if len(out) == 2 {
err, _ := out[1].Interface().(error)
if err != nil {
return nil, err
}
}
// set attribute
return out[0].Interface(), nil
}
}