diff --git a/lift.go b/lift.go index 7212945..47e18f0 100644 --- a/lift.go +++ b/lift.go @@ -6,8 +6,12 @@ import ( "strings" ) +// LiftedArgs represents a set of variables that have been lifted from expressions and +// replaced with identifiers, eg `id == "foo"` becomes `id == vars.a`, with "foo" lifted +// as "vars.a". type LiftedArgs interface { Get(val string) (any, bool) + Map() map[string]any } // liftLiterals lifts quoted literals into variables, allowing us to normalize @@ -128,6 +132,14 @@ type pointerArgMap struct { vars map[string]argMapValue } +func (p pointerArgMap) Map() map[string]any { + res := map[string]any{} + for k, v := range p.vars { + res[k] = v.get(p.expr) + } + return res +} + func (p pointerArgMap) Get(key string) (any, bool) { val, ok := p.vars[key] if !ok { @@ -151,3 +163,7 @@ func (p regularArgMap) Get(key string) (any, bool) { val, ok := p[key] return val, ok } + +func (p regularArgMap) Map() map[string]any { + return p +} diff --git a/parser.go b/parser.go index 12b8a82..1793a21 100644 --- a/parser.go +++ b/parser.go @@ -545,7 +545,7 @@ func callToPredicate(item celast.Expr, negated bool, vars LiftedArgs) *Predicate } } - if aIsVar { + if aIsVar && vars != nil { if val, ok := vars.Get(strings.TrimPrefix(identA, VarPrefix)); ok { // Normalize. literal = val @@ -554,7 +554,7 @@ func callToPredicate(item celast.Expr, negated bool, vars LiftedArgs) *Predicate } } - if bIsVar { + if bIsVar && vars != nil { if val, ok := vars.Get(strings.TrimPrefix(identB, VarPrefix)); ok { // Normalize. literal = val diff --git a/parser_test.go b/parser_test.go index cf5452a..15d9db1 100644 --- a/parser_test.go +++ b/parser_test.go @@ -963,6 +963,9 @@ func TestParse_LiftedVars(t *testing.T) { test.expected.Evaluable = eval } + // Convert the lifted arg interfaces to the same map values + actual.Vars = regularArgMap(actual.Vars.Map()) + require.NoError(t, err) require.NotNil(t, actual)