Allow for pipe and dot mixing

This commit is contained in:
tidwall 2019-06-27 18:27:53 -07:00
parent 7b8705a6b6
commit 7660d0f79f
2 changed files with 65 additions and 4 deletions

View File

@ -866,9 +866,16 @@ func parseObjectPath(path string) (r objectPathResult) {
}
}
if path[i] == '.' {
// peek at the next byte and see if it's a '@' modifier.
r.part = path[:i]
r.path = path[i+1:]
r.more = true
if !DisableModifiers && !DisableChaining &&
i < len(path)-1 && path[i+1] == '@' {
r.pipe = path[i+1:]
r.piped = true
} else {
r.path = path[i+1:]
r.more = true
}
return
}
if path[i] == '*' || path[i] == '?' {
@ -892,7 +899,15 @@ func parseObjectPath(path string) (r objectPathResult) {
continue
} else if path[i] == '.' {
r.part = string(epart)
r.path = path[i+1:]
// peek at the next byte and see if it's a '@' modifier
if !DisableModifiers && !DisableChaining &&
i < len(path)-1 && path[i+1] == '@' {
r.pipe = path[i+1:]
r.piped = true
} else {
r.path = path[i+1:]
r.more = true
}
r.more = true
return
} else if path[i] == '|' {
@ -1515,7 +1530,7 @@ func Get(json, path string) Result {
var rjson string
path, rjson, ok = execModifier(json, path)
if ok {
if len(path) > 0 && path[0] == '|' {
if len(path) > 0 && (path[0] == '|' || path[0] == '.') {
res := Get(rjson, path[1:])
res.Index = 0
return res
@ -2282,6 +2297,11 @@ func execModifier(json, path string) (pathOut, res string, ok bool) {
break
}
}
if path[i] == '.' {
pathOut = path[i:]
name = path[1:i]
break
}
}
if fn, ok := modifiers[name]; ok {
var args string

View File

@ -1613,3 +1613,44 @@ func TestArrayEx(t *testing.T) {
t.Fatalf("expected '%v', got '%v'", "2", res)
}
}
func TestPipeDotMixing(t *testing.T) {
json := `{
"info": {
"friends": [
{"first": "Dale", "last": "Murphy", "age": 44},
{"first": "Roger", "last": "Craig", "age": 68},
{"first": "Jane", "last": "Murphy", "age": 47}
]
}
}`
var res string
res = Get(json, `info.friends.#[first="Dale"].last`).String()
if res != "Murphy" {
t.Fatalf("expected '%v', got '%v'", "Murphy", res)
}
res = Get(json, `info|friends.#[first="Dale"].last`).String()
if res != "Murphy" {
t.Fatalf("expected '%v', got '%v'", "Murphy", res)
}
res = Get(json, `info|friends.#[first="Dale"]|last`).String()
if res != "Murphy" {
t.Fatalf("expected '%v', got '%v'", "Murphy", res)
}
res = Get(json, `info|friends|#[first="Dale"]|last`).String()
if res != "Murphy" {
t.Fatalf("expected '%v', got '%v'", "Murphy", res)
}
res = Get(json, `@ugly|info|friends|#[first="Dale"]|last`).String()
if res != "Murphy" {
t.Fatalf("expected '%v', got '%v'", "Murphy", res)
}
res = Get(json, `@ugly|info.@ugly|friends|#[first="Dale"]|last`).String()
if res != "Murphy" {
t.Fatalf("expected '%v', got '%v'", "Murphy", res)
}
res = Get(json, `@ugly.info|@ugly.friends|#[first="Dale"]|last`).String()
if res != "Murphy" {
t.Fatalf("expected '%v', got '%v'", "Murphy", res)
}
}