From 568515c072244d6d6f99140adcb7b326e5ec61e7 Mon Sep 17 00:00:00 2001 From: Notealot Date: Sun, 18 Feb 2024 22:33:06 +0800 Subject: [PATCH 1/2] add new method --- ast/node.go | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/ast/node.go b/ast/node.go index 7ab2b03c1..b9f4db65f 100644 --- a/ast/node.go +++ b/ast/node.go @@ -851,19 +851,30 @@ func (self *Node) IndexPair(idx int) *Pair { return self.skipIndexPair(idx) } +func (self *Node) indexOrGet(idx int, key string) (*Node, int) { + if err := self.should(types.V_OBJECT, "an object"); err != nil { + return unwrapError(err), idx + } + + pr := self.skipIndexPair(idx) + if pr != nil && pr.Key == key { + return &pr.Value, idx + } + + return self.skipKey(key) +} + // IndexOrGet firstly use idx to index a value and check if its key matches // If not, then use the key to search value func (self *Node) IndexOrGet(idx int, key string) *Node { - if err := self.should(types.V_OBJECT, "an object"); err != nil { - return unwrapError(err) - } + node, _ := self.indexOrGet(idx, key) + return node +} - pr := self.skipIndexPair(idx) - if pr != nil && pr.Key == key { - return &pr.Value - } - n, _ := self.skipKey(key) - return n +// IndexOrGetWithIdx attempts to retrieve a node by index and key, returning the node and its correct index. +// If the key does not match at the given index, it searches by key and returns the node with its updated index. +func (self *Node) IndexOrGetWithIdx(idx int, key string) (*Node, int) { + return self.indexOrGet(idx, key) } /** Generic Value Converters **/ From bbccb4d8fe43cb779e4c3efc44a80ad7e7c7e8f1 Mon Sep 17 00:00:00 2001 From: Notealot Date: Sun, 18 Feb 2024 22:47:46 +0800 Subject: [PATCH 2/2] add test cases --- ast/node_test.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ast/node_test.go b/ast/node_test.go index 7fb0da35d..065b6c87d 100644 --- a/ast/node_test.go +++ b/ast/node_test.go @@ -250,6 +250,17 @@ func TestIndexOrGet(t *testing.T) { } } +func TestIndexOrGetWithIdx(t *testing.T) { + root, _ := NewParser(`{"a":1,"b":2}`).Parse() + b, idx := root.IndexOrGetWithIdx(0, "b") + if v, err := b.Int64(); err != nil || v != int64(2) { + t.Fatal(b, idx) + } + if idx != 1 { + t.Fatal(b, idx) + } +} + func TestTypeCast(t *testing.T) { type tcase struct { method string