Skip to content

Commit

Permalink
simplfied match result to []interface{} and added extension for acces…
Browse files Browse the repository at this point in the history
…ss to wildcards values of a match
  • Loading branch information
JanErik Keller committed Oct 24, 2017
1 parent 45ad7c3 commit 463a233
Show file tree
Hide file tree
Showing 8 changed files with 596 additions and 223 deletions.
12 changes: 6 additions & 6 deletions evaluable.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ func getSelectEvaluable(key gval.Evaluable) single {
}
}

// * / **
// * / [*]
func starEvaluable(c context.Context, r, v interface{}, m match) {
visitAll(v, func(key string, val interface{}) { m(key, val) })
}

// * / [] / [x, ...] / [*]
// [x, ...]
func getMultiSelectEvaluable(keys []gval.Evaluable) multi {
if len(keys) == 0 {
return starEvaluable
Expand Down Expand Up @@ -88,15 +88,15 @@ func selectValue(c context.Context, key gval.Evaluable, r, v interface{}) (value

//..
func mapperEvaluable(c context.Context, r, v interface{}, m match) {
m("", v)
m([]interface{}{}, v)
visitAll(v, func(wildcard string, v interface{}) {
mapperEvaluable(c, r, v, func(key string, v interface{}) {
m("["+strconv.Quote(wildcard)+"]"+key, v)
mapperEvaluable(c, r, v, func(key interface{}, v interface{}) {
m(append([]interface{}{wildcard}, key.([]interface{})...), v)
})
})
}

func visitAll(v interface{}, visit match) {
func visitAll(v interface{}, visit func(key string, v interface{})) {
switch v := v.(type) {
case []interface{}:
for i, e := range v {
Expand Down
18 changes: 9 additions & 9 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ func ExampleGet_wildcard() {
os.Exit(1)
}

for wildcards, value := range welcome.(jsonpath.Matchs) {
fmt.Printf("%s -> %v\n", (*wildcards)[0], value)
for _, value := range welcome.([]interface{}) {
fmt.Printf("%v\n", value)
}

// Output
// 0 -> Hello World!
// 1 -> Good Morning
// Hello World!
// Good Morning
}

func ExampleGet_filter() {
Expand All @@ -71,7 +71,7 @@ func ExampleGet_filter() {
os.Exit(1)
}

for _, value := range welcome.(jsonpath.Matchs) {
for _, value := range welcome.([]interface{}) {
fmt.Println(value)
}

Expand All @@ -80,9 +80,9 @@ func ExampleGet_filter() {
}

func Example() {
builder := gval.Full(jsonpath.Language())
builder := gval.Full(jsonpath.WildcardExtension())

path, err := builder.NewEvaluable("$..[[email protected] && @.speed > 100].name")
path, err := builder.NewEvaluable("{#1: $..[[email protected] && @.speed > 100].name}")
if err != nil {
fmt.Println(err)
os.Exit(1)
Expand Down Expand Up @@ -127,8 +127,8 @@ func Example() {
os.Exit(1)
}

for wildcards, device := range devices.(jsonpath.Matchs) {
fmt.Printf("%s -> %v\n", (*wildcards)[1], device)
for device, name := range devices.(map[string]interface{}) {
fmt.Printf("%s -> %v\n", device, name)
}

// Unordered output:
Expand Down
36 changes: 20 additions & 16 deletions jsonpath.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
package jsonpath

// jsonpath is an implementation of http://goessner.net/articles/JsonPath/
// If a JSONPath contains one of
// [key1, key2 ...], .., *, [min:max], [min:max:step], (? expression)
// all matchs are listed in an []interface{}
//
// The package comes with an extension of JSONPath to access the wildcard values of a match.
// If the JSONPath is used inside of a JSON object, you can use '#' or '#i' with natural number i
// to access all wildcards values or the ith wildcard

import (
"context"
"fmt"

"github.com/PaesslerAG/gval"
)

// New returns an selector for given jsonpath
// If the JSON Path plainly the selector returns all Matchs
// A JSON Path is not plain if it contains one of
// [key1, key2 ...], .., *, [min:max], [min:max:step], (? expression)
func New(path string) (gval.Evaluable, error) {
return lang.NewEvaluable(path)
}
Expand All @@ -24,25 +29,24 @@ func Get(path string, value interface{}) (interface{}, error) {
return eval(context.Background(), value)
}

type match func(key string, v interface{})

//Matchs of a jsonpath. The key is an Pointer to an Array of the Values used for the wildcards in the jsonpath
type Matchs = map[*Wildcards]interface{}

//Wildcards TODO find correct name
type Wildcards []string

var lang = gval.NewLanguage(
gval.Base(),
gval.PrefixExtension('$', parse(getRootEvaluable)),
gval.PrefixExtension('@', parse(getCurrentEvaluable)),
gval.PrefixExtension('$', single(getRootEvaluable).parse),
gval.PrefixExtension('@', single(getCurrentEvaluable).parse),
)

//Language is the jsonpath Language
func Language() gval.Language {
return lang
}

func (w Wildcards) String() string {
return fmt.Sprint([]string(w))
var wildcardExtension = gval.NewLanguage(
lang,
gval.PrefixExtension('{', parseJSONObject),
gval.PrefixExtension('#', parseMatchReference),
)

//WildcardExtension is the jsonpath Language with access to the values, that matchs used wildcards
func WildcardExtension() gval.Language {
return wildcardExtension
}
Loading

0 comments on commit 463a233

Please sign in to comment.