From eded43bdc6a0d99473d806fb7dd90a9a80281138 Mon Sep 17 00:00:00 2001 From: Anand Krishnamoorthi Date: Mon, 20 Feb 2023 07:57:30 -0800 Subject: [PATCH] Fix key, value in membership and some-in Signed-off-by: Anand Krishnamoorthi --- src/ast.rs | 8 +-- src/interpreter.rs | 50 +++++++------------ src/parser.rs | 12 +++-- .../parser/cases/expressions/array-compr.yaml | 15 +++--- tests/parser/cases/expressions/in.yaml | 6 +-- .../parser/cases/expressions/membership.yaml | 3 +- tests/parser/cases/expressions/object.yaml | 4 +- tests/parser/cases/expressions/set-compr.yaml | 15 +++--- tests/parser/cases/some/some.in.yaml | 13 ++--- tests/parser/mod.rs | 8 +-- 10 files changed, 60 insertions(+), 74 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index 6036195..9023b2f 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -136,8 +136,8 @@ pub enum Expr<'source> { Membership { span: Span<'source>, - key: Box>, - value: Box>>, + key: Box>>, + value: Box>, collection: Box>, }, } @@ -174,8 +174,8 @@ pub enum Literal<'source> { }, SomeIn { span: Span<'source>, - key: Expr<'source>, - value: Option>, + key: Option>, + value: Expr<'source>, collection: Expr<'source>, }, Expr { diff --git a/src/interpreter.rs b/src/interpreter.rs index 860c052..7af2a0a 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -233,10 +233,10 @@ impl<'source> Interpreter<'source> { collection, .. } => { - self.hoist_loops_impl(key, loops); - if let Some(value) = value.as_ref() { - self.hoist_loops_impl(value, loops); + if let Some(key) = key.as_ref() { + self.hoist_loops_impl(key, loops); } + self.hoist_loops_impl(value, loops); self.hoist_loops_impl(collection, loops); } @@ -258,10 +258,10 @@ impl<'source> Interpreter<'source> { collection, .. } => { - self.hoist_loops_impl(key, &mut loops); - if let Some(value) = value { - self.hoist_loops_impl(value, &mut loops); + if let Some(key) = key { + self.hoist_loops_impl(key, &mut loops); } + self.hoist_loops_impl(value, &mut loops); self.hoist_loops_impl(collection, &mut loops); } Every { @@ -548,18 +548,8 @@ impl<'source> Interpreter<'source> { } true } - Literal::SomeIn { - key, - value, - collection, - .. - } => { - let value = self.eval_membership(key, value, collection)?; - if let Value::Bool(bool) = value { - bool - } else { - panic!(); - } + Literal::SomeIn { .. } => { + unimplemented!() } Literal::NotExpr { expr, .. } => matches!(self.eval_expr(expr)?, Value::Bool(false)), Literal::Every { @@ -861,37 +851,35 @@ impl<'source> Interpreter<'source> { fn eval_membership( &mut self, - key: &'source Expr<'source>, - value: &'source Option>, + key: &'source Option>, + value: &'source Expr<'source>, collection: &'source Expr<'source>, ) -> Result { - let key = self.eval_expr(key)?; - + let value = self.eval_expr(value)?; let collection = self.eval_expr(collection)?; let result = match &collection { Value::Array(array) => { - if let Some(value) = value { - let value = self.eval_expr(value)?; + if let Some(key) = key { + let key = self.eval_expr(key)?; collection[&key] == value } else { - array.iter().any(|item| *item == key) + array.iter().any(|item| *item == value) } } Value::Object(object) => { - if let Some(value) = value { - let value = self.eval_expr(value)?; + if let Some(key) = key { + let key = self.eval_expr(key)?; collection[&key] == value } else { - object.values().into_iter().any(|item| *item == key) + object.values().into_iter().any(|item| *item == value) } } Value::Set(set) => { - if value.is_some() { + if key.is_some() { false - //return Err(anyhow!("key-value pair is not supported for set")); } else { - set.contains(&key) + set.contains(&value) } } _ => { diff --git a/src/parser.rs b/src/parser.rs index 11edddb..8ebb1f8 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -690,10 +690,14 @@ impl<'source> Parser<'source> { self.parse_future_keyword("in", false, "while parsing membership expression")?; let expr3 = self.parse_bool_expr()?; span.end = self.end; + let (key, value) = match expr2 { + Some(e) => (Box::new(Some(expr1)), Box::new(e)), + None => (Box::new(None), Box::new(expr1)), + }; expr1 = Expr::Membership { span, - key: Box::new(expr1), - value: Box::new(expr2), + key, + value, collection: Box::new(expr3), }; expr2 = None; @@ -856,8 +860,8 @@ impl<'source> Parser<'source> { } let (key, value) = match refs.len() { - 2 => (refs[0].clone(), Some(refs[1].clone())), - 1 => (refs[0].clone(), None), + 2 => (Some(refs[0].clone()), refs[1].clone()), + 1 => (None, refs[0].clone()), _ => { let span = &vars[2]; return Err(anyhow!( diff --git a/tests/parser/cases/expressions/array-compr.yaml b/tests/parser/cases/expressions/array-compr.yaml index 14619d3..1da6b03 100644 --- a/tests/parser/cases/expressions/array-compr.yaml +++ b/tests/parser/cases/expressions/array-compr.yaml @@ -29,7 +29,7 @@ cases: expr: var: y bodies: [] - + - note: case2-array rego: | package test @@ -56,7 +56,7 @@ cases: var: y - number: 5 bodies: [] - + - note: case3-compr rego: | package test @@ -92,7 +92,7 @@ cases: set: - number: 5 bodies: [] - + - note: case4-array rego: | package test @@ -119,14 +119,14 @@ cases: rhs: var: y - inexpr: - key: + value: number: 5 collection: set: - number: 5 - - number: 6 + - number: 6 bodies: [] - + - note: case5-array rego: | package test @@ -159,7 +159,7 @@ cases: rhs: var: y - inexpr: - key: + value: number: 5 collection: set: @@ -206,4 +206,3 @@ cases: set: - number: 5 bodies: [] - diff --git a/tests/parser/cases/expressions/in.yaml b/tests/parser/cases/expressions/in.yaml index 887e946..fc742c3 100644 --- a/tests/parser/cases/expressions/in.yaml +++ b/tests/parser/cases/expressions/in.yaml @@ -24,7 +24,7 @@ cases: op: "=" value: inexpr: - key: + value: number: 5 collection: array: @@ -40,9 +40,9 @@ cases: op: "=" value: inexpr: - key: + value: inexpr: - key: + value: number: 5 collection: array: diff --git a/tests/parser/cases/expressions/membership.yaml b/tests/parser/cases/expressions/membership.yaml index 2d3430a..5c3183f 100644 --- a/tests/parser/cases/expressions/membership.yaml +++ b/tests/parser/cases/expressions/membership.yaml @@ -39,7 +39,7 @@ cases: op: "=" value: inexpr: - key: + value: inexpr: key: number: 0 @@ -50,4 +50,3 @@ cases: collection: var: d bodies: [] - diff --git a/tests/parser/cases/expressions/object.yaml b/tests/parser/cases/expressions/object.yaml index 7a22bb7..25892e5 100644 --- a/tests/parser/cases/expressions/object.yaml +++ b/tests/parser/cases/expressions/object.yaml @@ -153,11 +153,11 @@ cases: string: q - key: inexpr: - key: + value: string: r collection: string: d value: string: e - + bodies: [] diff --git a/tests/parser/cases/expressions/set-compr.yaml b/tests/parser/cases/expressions/set-compr.yaml index 9e18c4d..dec0fe7 100644 --- a/tests/parser/cases/expressions/set-compr.yaml +++ b/tests/parser/cases/expressions/set-compr.yaml @@ -29,7 +29,7 @@ cases: expr: var: y bodies: [] - + - note: case2-set rego: | package test @@ -56,7 +56,7 @@ cases: var: y - number: 5 bodies: [] - + - note: case3-compr rego: | package test @@ -92,7 +92,7 @@ cases: set: - number: 5 bodies: [] - + - note: case4-set rego: | package test @@ -119,14 +119,14 @@ cases: rhs: var: y - inexpr: - key: + value: number: 5 collection: set: - number: 5 - - number: 6 + - number: 6 bodies: [] - + - note: case5-set rego: | package test @@ -159,7 +159,7 @@ cases: rhs: var: y - inexpr: - key: + value: number: 5 collection: set: @@ -206,4 +206,3 @@ cases: set: - number: 5 bodies: [] - diff --git a/tests/parser/cases/some/some.in.yaml b/tests/parser/cases/some/some.in.yaml index 6fb783f..2fc717a 100644 --- a/tests/parser/cases/some/some.in.yaml +++ b/tests/parser/cases/some/some.in.yaml @@ -34,7 +34,7 @@ cases: - span: some a in {1} literal: some-decl: - key: + value: var: a collection: set: @@ -140,8 +140,8 @@ cases: y = a } error: expecting `}` while parsing query - - - note: multi-line-parsed as membership + + - note: multi-line-parsed-as-membership rego: | package test import future.keywords.in @@ -165,7 +165,7 @@ cases: assign: op: := value: - number: 5 + number: 5 bodies: [] - spec: head: @@ -189,7 +189,7 @@ cases: expr: inexpr: span: b in {4, 5} - key: + value: var: b collection: set: @@ -221,6 +221,3 @@ cases: var: y rhs: var: a - - - diff --git a/tests/parser/mod.rs b/tests/parser/mod.rs index d4a924b..fde1c0f 100644 --- a/tests/parser/mod.rs +++ b/tests/parser/mod.rs @@ -226,8 +226,8 @@ fn match_expr_impl(e: &Expr, v: &Value) -> Result<()> { collection, } => { match_span_opt(span, &v["inexpr"]["span"])?; - match_expr(key, &v["inexpr"]["key"])?; - match_expr_opt(span, value, &v["inexpr"]["value"])?; + match_expr_opt(span, key, &v["inexpr"]["key"])?; + match_expr(value, &v["inexpr"]["value"])?; match_expr(collection, &v["inexpr"]["collection"]) } } @@ -494,8 +494,8 @@ fn match_literal(l: &Literal, v: &Value) -> Result<()> { } => { let v = &v["some-decl"]; match_span_opt(span, &v["span"])?; - match_expr(key, &v["key"])?; - match_expr_opt(span, value, &v["value"])?; + match_expr(value, &v["value"])?; + match_expr_opt(span, key, &v["key"])?; match_expr(collection, &v["collection"]) } Literal::Expr { expr, .. } => match_expr(expr, &v["expr"]),