This repository was archived by the owner on Aug 15, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 604
Expand file tree
/
Copy pathcallback.go
More file actions
69 lines (64 loc) · 1.63 KB
/
callback.go
File metadata and controls
69 lines (64 loc) · 1.63 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
package dnode
import (
"fmt"
"reflect"
"strconv"
"strings"
)
type Callback func(args ...interface{})
func (p *Callback) UnmarshalJSON(data []byte) error {
return nil
}
type CallbackSpec struct {
Path []string
Callback Callback
}
func (c *CallbackSpec) Apply(value reflect.Value) error {
i := 0
for {
switch value.Kind() {
case reflect.Slice:
if i == len(c.Path) {
return fmt.Errorf("Callback path too short: %v", c.Path)
}
index, err := strconv.Atoi(c.Path[i])
if err != nil {
return fmt.Errorf("Integer expected in callback path, got '%v'.", c.Path[i])
}
value = value.Index(index)
i++
case reflect.Map:
if i == len(c.Path) {
return fmt.Errorf("Callback path too short: %v", c.Path)
}
if i == len(c.Path)-1 && value.Type().Elem().Kind() == reflect.Interface {
value.SetMapIndex(reflect.ValueOf(c.Path[i]), reflect.ValueOf(c.Callback))
return nil
}
value = value.MapIndex(reflect.ValueOf(c.Path[i]))
i++
case reflect.Ptr:
value = value.Elem()
case reflect.Interface:
if i == len(c.Path) {
value.Set(reflect.ValueOf(c.Callback))
return nil
}
value = value.Elem()
case reflect.Struct:
if innerPartial, ok := value.Addr().Interface().(*Partial); ok {
innerPartial.callbacks = append(innerPartial.callbacks, CallbackSpec{c.Path[i:], c.Callback})
return nil
}
name := c.Path[i]
value = value.FieldByName(strings.ToUpper(name[0:1]) + name[1:])
i++
case reflect.Func:
value.Set(reflect.ValueOf(c.Callback))
return nil
default:
return fmt.Errorf("Unhandled value of kind '%v' in callback path.", value.Kind())
}
}
return nil
}