-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathref.go
54 lines (50 loc) · 1.01 KB
/
ref.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
package jsonlogic
import (
"strconv"
"strings"
)
func deref(data interface{}, ref []string) interface{} {
if len(ref) == 0 {
return nil
}
switch data := data.(type) {
case []interface{}:
index, err := strconv.Atoi(ref[0])
if err != nil || index < 0 || index+1 > len(data) {
return nil
}
val := data[index]
if len(ref) == 1 {
return val
}
return deref(val, ref[1:])
case map[string]interface{}:
val, ok := data[ref[0]]
if !ok {
return nil
}
if len(ref) == 1 {
return val
}
return deref(val, ref[1:])
}
return nil
}
// DottedRef attempts to resolve a dotted reference into a
// Go type. Only map[string]interface{} is supported for now.
func DottedRef(data interface{}, ref interface{}) interface{} {
var refStr string
switch ref := ref.(type) {
case string:
refStr = ref
case float64:
intref := int(ref)
if ref != float64(intref) || intref < 0 {
return nil
}
refStr = strconv.Itoa(intref)
default:
return nil
}
return deref(data, strings.Split(refStr, "."))
}