From 5613674d9320a27147366dbdbc3807319e7e6cfe Mon Sep 17 00:00:00 2001 From: Dmitry Dodzin Date: Wed, 18 Jun 2025 20:22:42 +0300 Subject: [PATCH 1/2] Add pipe operator --- src/lib.rs | 19 +++++++++++++++++++ src/parser/jslt.pest | 3 ++- src/transform/expr.rs | 9 +++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 502f439..980417e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -230,6 +230,25 @@ mod tests { Ok(()) } + #[test] + fn pipe_operator() -> Result<()> { + let jslt: Jslt = r#" + .menu.popup.menuitem | { + "result" : { + "Open" : .[0].onclick, + "Close" : .[1].onclick + } + } + "# + .parse()?; + + let output = jslt.transform_value(&BASIC_INPUT)?; + + assert_eq!(&output, BASIC_OUTPUT.deref()); + + Ok(()) + } + #[test] fn object_for() -> Result<()> { let jslt: Jslt = r#" diff --git a/src/parser/jslt.pest b/src/parser/jslt.pest index 6dc5afc..8788551 100644 --- a/src/parser/jslt.pest +++ b/src/parser/jslt.pest @@ -6,7 +6,7 @@ Expr = _{ OperatorExpr | ValueExpr } ValueExpr = _{ VariableDef | FunctionDef | IfStatement | Value } OperatorExpr = { ValueExpr ~ (Operator ~ ValueExpr)+ } -Operator = _{ Add | Sub | Div | Mul | Gte | Gt | Lte | Lt | And | Or | Equal | NotEqual } +Operator = _{ Add | Sub | Div | Mul | Gte | Gt | Lte | Lt | And | Or | Equal | NotEqual | Pipe } Add = { "+" } Sub = { "-" } @@ -20,6 +20,7 @@ Equal = { "==" } NotEqual = { "!=" } And = { "and" } Or = { "or" } +Pipe = { "|" } If = _{ "if" } For = _{ "for" } Def = _{ "def" } diff --git a/src/transform/expr.rs b/src/transform/expr.rs index 259ba87..a941d9e 100644 --- a/src/transform/expr.rs +++ b/src/transform/expr.rs @@ -92,6 +92,7 @@ pub enum OperatorTransformer { Lte, Equal, NotEqual, + Pipe, } impl fmt::Display for OperatorTransformer { @@ -109,6 +110,7 @@ impl fmt::Display for OperatorTransformer { OperatorTransformer::Lte => f.write_str("<="), OperatorTransformer::Equal => f.write_str("=="), OperatorTransformer::NotEqual => f.write_str("!="), + OperatorTransformer::Pipe => f.write_str("|"), } } } @@ -172,6 +174,7 @@ impl OperatorExprTransformer { impl_operator_parse!(pairs, Sub); impl_operator_parse!(pairs, Mul); impl_operator_parse!(pairs, Div); + impl_operator_parse!(pairs, Pipe); Err(JsltError::InvalidInput(format!( "Could not evaluate the expession {pairs:#?}", @@ -192,6 +195,11 @@ impl Transform for OperatorExprTransformer { let left = self .lhs .transform_value(Context::Borrowed(&context), input)?; + + if matches!(self.operator, OperatorTransformer::Pipe) { + return self.rhs.transform_value(context, &left); + } + let right = self.rhs.transform_value(context, input)?; match self.operator { @@ -386,6 +394,7 @@ impl Transform for OperatorExprTransformer { }, OperatorTransformer::Equal => Ok(Value::Bool(left == right)), OperatorTransformer::NotEqual => Ok(Value::Bool(left != right)), + OperatorTransformer::Pipe => unreachable!(), } } } From 0cb21f9afaca48b6d2692f57602ff84e592313aa Mon Sep 17 00:00:00 2001 From: Dmitry Dodzin Date: Wed, 18 Jun 2025 20:27:35 +0300 Subject: [PATCH 2/2] make test double pipe --- src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 980417e..c94dd65 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -234,10 +234,10 @@ mod tests { fn pipe_operator() -> Result<()> { let jslt: Jslt = r#" .menu.popup.menuitem | { - "result" : { - "Open" : .[0].onclick, - "Close" : .[1].onclick - } + "Open" : .[0].onclick, + "Close" : .[1].onclick + } | { + "result" : . } "# .parse()?;