From c37c5b3cf3a02d21b9e01e2354bf12d7bd05a5b1 Mon Sep 17 00:00:00 2001 From: elkowar <5300871+elkowar@users.noreply.github.com> Date: Tue, 2 Mar 2021 14:52:51 +0100 Subject: [PATCH] Add elvis operator --- docs/content/main/examples.md | 2 +- docs/content/main/expression_language.md | 4 +++- src/value/attr_value/attr_value_expr.rs | 3 +++ src/value/attr_value/parser.rs | 1 + src/value/primitive.rs | 2 +- 5 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/content/main/examples.md b/docs/content/main/examples.md index ba97a32..2e0a55d 100644 --- a/docs/content/main/examples.md +++ b/docs/content/main/examples.md @@ -1,7 +1,7 @@ +++ title = "Examples" slug = "Sample configs" -weight = 5 +weight = 6 +++ ## Example Configurations diff --git a/docs/content/main/expression_language.md b/docs/content/main/expression_language.md index 9984d0e..82604cc 100644 --- a/docs/content/main/expression_language.md +++ b/docs/content/main/expression_language.md @@ -1,7 +1,7 @@ +++ title = "Eww expressions" slug = "Embedded eww expression language" -weight = 6 +weight = 5 +++ # The embedded Eww expression-language @@ -27,6 +27,8 @@ The expression language supports: - simple mathematical operations (`+`, `-`, `*`, `/`, `%`) - comparisons (`==`, `!=`, `>`, `<`) - boolean operations (`||`, `&&`, `!`) +- elvis operator (`?:`) + - if the left side is `""`, then returns the right side, otherwise evaluates to the left side. - conditionals (`if condition then 'value' else 'other value'`) - numbers, strings, booleans and variable references (`12`, `'hi'`, `true`, `some_variable`) - strings can contain other expressions again: `'foo {{some_variable}} bar'` diff --git a/src/value/attr_value/attr_value_expr.rs b/src/value/attr_value/attr_value_expr.rs index 43bc7ee..cb0f9cb 100644 --- a/src/value/attr_value/attr_value_expr.rs +++ b/src/value/attr_value/attr_value_expr.rs @@ -16,6 +16,7 @@ pub enum BinOp { Or, GT, LT, + Elvis, } impl std::fmt::Display for BinOp { @@ -32,6 +33,7 @@ impl std::fmt::Display for BinOp { BinOp::Or => write!(f, "||"), BinOp::GT => write!(f, ">"), BinOp::LT => write!(f, "<"), + BinOp::Elvis => write!(f, "?:"), } } } @@ -150,6 +152,7 @@ impl AttrValueExpr { BinOp::Mod => PrimitiveValue::from(a.as_f64()? % b.as_f64()?), BinOp::GT => PrimitiveValue::from(a.as_f64()? > b.as_f64()?), BinOp::LT => PrimitiveValue::from(a.as_f64()? < b.as_f64()?), + BinOp::Elvis => PrimitiveValue::from(if a.0.is_empty() { b } else { a }), }) } AttrValueExpr::UnaryOp(op, a) => { diff --git a/src/value/attr_value/parser.rs b/src/value/attr_value/parser.rs index 14ca0d3..ce63fd9 100644 --- a/src/value/attr_value/parser.rs +++ b/src/value/attr_value/parser.rs @@ -131,6 +131,7 @@ pub fn parse_expr(i: &str) -> IResult<&str, AttrValueExpr, VerboseError<&str>> { let (i, remainder) = many0(alt(( map(preceded(tag("&&"), parse_term1), |x| (BinOp::And, x)), map(preceded(tag("||"), parse_term1), |x| (BinOp::Or, x)), + map(preceded(tag("?:"), parse_term1), |x| (BinOp::Elvis, x)), )))(i)?; let exprs = remainder diff --git a/src/value/primitive.rs b/src/value/primitive.rs index 98891f1..d869d00 100644 --- a/src/value/primitive.rs +++ b/src/value/primitive.rs @@ -6,7 +6,7 @@ use std::{convert::TryFrom, fmt, iter::FromIterator}; use crate::impl_try_from; #[derive(Clone, Deserialize, Serialize, derive_more::From, Default)] -pub struct PrimitiveValue(String); +pub struct PrimitiveValue(pub String); impl fmt::Display for PrimitiveValue { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {