json/query.go

44 lines
970 B
Go

package json
import (
"fmt"
"strconv"
"strings"
)
func Query(parent Node, path []string) (Node, error) {
if len(path) == 0 {
return parent, nil
}
head, rest := path[0], path[1:]
switch parent := parent.(type) {
case ObjectNode:
next, ok := parent.GetByKey(head)
if !ok {
return nil, fmt.Errorf("key %s not found at object %v", head, parent)
}
return Query(next, rest)
case ArrayNode:
stringIdx := strings.Trim(head, "[]")
idx, err := strconv.Atoi(stringIdx)
if err != nil {
return nil, fmt.Errorf("key %s is invalid index: %w", stringIdx, err)
}
if idx >= parent.Len() {
return nil, fmt.Errorf("index %d is out of range (len=%d)", idx, parent.Len())
}
next := parent.Index(idx)
return Query(next, rest)
default:
return nil, fmt.Errorf("can't get key=%s from node type = %t", head, parent)
}
}
func MustQuery(parent Node, path []string) Node {
n, err := Query(parent, path)
if err != nil {
panic(err)
}
return n
}