From c1dbc71f8b41b62ebf160e40a774edb892080cf8 Mon Sep 17 00:00:00 2001 From: Leon Mika Date: Sun, 29 Jul 2018 19:46:04 +1000 Subject: [PATCH] Added pointer dereferencing for field extraction --- eval_test.go | 33 +++++++++++++++++++++++++++++++++ utils.go | 5 +++++ 2 files changed, 38 insertions(+) diff --git a/eval_test.go b/eval_test.go index 00684e6cc..68c67f6fc 100644 --- a/eval_test.go +++ b/eval_test.go @@ -129,6 +129,11 @@ var evalTests = []evalTest{ struct{ Foo struct{ Bar bool } }{Foo: struct{ Bar bool }{Bar: true}}, true, }, + { + `Foo.Bar`, + &struct{ Foo *struct{ Bar bool } }{Foo: &struct{ Bar bool }{Bar: true}}, + true, + }, { "foo[2]", map[string]interface{}{"foo": []rune{'a', 'b', 'c'}}, @@ -162,6 +167,29 @@ var evalTests = []evalTest{ }{1, 1}, true, }, + { + `[true][A]`, + &struct{ A int }{0}, + true, + }, + { + `A-1`, + &struct{ A int }{1}, + float64(0), + }, + { + `A == 0`, + &struct{ A uint8 }{0}, + true, + }, + { + `A == B`, + &struct { + A uint8 + B float64 + }{1, 1}, + true, + }, { `5 in 0..9`, nil, @@ -187,6 +215,11 @@ var evalTests = []evalTest{ map[string]interface{}{"foo": map[string]interface{}{"bar": map[string]interface{}{"baz": true}}}, true, }, + { + "foo.Bar['baz']", + map[string]interface{}{"foo": &struct{ Bar map[string]interface{}}{Bar: map[string]interface{}{"baz": true}}}, + true, + }, { `60 & 13`, nil, diff --git a/utils.go b/utils.go index 2ae27bce3..64966bb5e 100644 --- a/utils.go +++ b/utils.go @@ -90,6 +90,11 @@ func extract(from interface{}, it interface{}) (interface{}, error) { if value.IsValid() && value.CanInterface() { return value.Interface(), nil } + case reflect.Ptr: + derefValue := reflect.ValueOf(from).Elem() + if derefValue.IsValid() && derefValue.CanInterface() { + return extract(derefValue.Interface(), it) + } } } return nil, fmt.Errorf("can't get %q from %T", it, from)