Skip to content

Commit

Permalink
check reflect for nil pointer type and check nil for interface{} type…
Browse files Browse the repository at this point in the history
… nil
  • Loading branch information
abdularis committed Jun 1, 2021
1 parent 4f5f9c0 commit 27b1dac
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
24 changes: 24 additions & 0 deletions example_test.go
Expand Up @@ -448,3 +448,27 @@ func ExampleParser_ParseSublanguage() {
// Output:
// hello world
}

func ExampleEvaluate_NullStructField() {
user := struct {
ProjectID *uint
}{}
user.ProjectID = nil // its nil

// alternatively: "ProjectID > 0" will return the same, because nil ptr will use zero value '0'
value, err := gval.Evaluate("(ProjectID ?? 0) > 0", user)
if err != nil {
fmt.Println(err)
}
fmt.Println(value)

value, err = gval.Evaluate("(ProjectID ?? 99) > 0", user)
if err != nil {
fmt.Println(err)
}
fmt.Println(value)

// Output:
// false
// true
}
8 changes: 8 additions & 0 deletions gval.go
Expand Up @@ -103,9 +103,17 @@ var full = NewLanguage(arithmetic, bitmask, text, propositionalLogic, ljson,
InfixOperator("in", inArray),

InfixShortCircuit("??", func(a interface{}) (interface{}, bool) {
if v := reflect.ValueOf(a); v.Kind() == reflect.Ptr && v.IsNil() {
return nil, false
}

return a, a != false && a != nil
}),
InfixOperator("??", func(a, b interface{}) (interface{}, error) {
if v := reflect.ValueOf(a); v.Kind() == reflect.Ptr && v.IsNil() {
return b, nil
}

if a == false || a == nil {
return b, nil
}
Expand Down
12 changes: 12 additions & 0 deletions operator.go
Expand Up @@ -131,6 +131,12 @@ func convertToBool(o interface{}) (bool, bool) {
return b, true
}
v := reflect.ValueOf(o)

if v.Kind() == reflect.Ptr && v.IsNil() {
// if nil return default zero value false
return false, true
}

for o != nil && v.Kind() == reflect.Ptr {
v = v.Elem()
o = v.Interface()
Expand Down Expand Up @@ -171,6 +177,12 @@ func convertToFloat(o interface{}) (float64, bool) {
return i, true
}
v := reflect.ValueOf(o)

if v.Kind() == reflect.Ptr && v.IsNil() {
// if nil return default zero value 0
return 0, true
}

for o != nil && v.Kind() == reflect.Ptr {
v = v.Elem()
o = v.Interface()
Expand Down

0 comments on commit 27b1dac

Please sign in to comment.