diff options
author | NeonXP <i@neonxp.dev> | 2022-12-27 02:37:02 +0300 |
---|---|---|
committer | NeonXP <i@neonxp.dev> | 2022-12-27 02:40:03 +0300 |
commit | 76a7f461ebbde70ea0e3d4f9b79c08139acaee7c (patch) | |
tree | 5e6dcb05f00be5109b3465ef16a6e9169a27497e /query.go | |
parent | 6f1d1df79f161cfc695f74d271d689ba72c44d09 (diff) |
Completely rewritedv0.1.0
Diffstat (limited to 'query.go')
-rw-r--r-- | query.go | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/query.go b/query.go new file mode 100644 index 0000000..69b778c --- /dev/null +++ b/query.go @@ -0,0 +1,43 @@ +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 +} |