[libshumate] vector: Add case expression



commit 345dc7f5081a6cebb28cc87ca3d3243abdc2adab
Author: James Westman <james jwestman net>
Date:   Sat Sep 24 23:05:04 2022 -0500

    vector: Add case expression

 shumate/vector/shumate-vector-expression-filter.c | 32 +++++++++++++++++++++++
 tests/vector-expression.c                         |  4 +++
 2 files changed, 36 insertions(+)
---
diff --git a/shumate/vector/shumate-vector-expression-filter.c 
b/shumate/vector/shumate-vector-expression-filter.c
index de64cbd..5d6bce9 100644
--- a/shumate/vector/shumate-vector-expression-filter.c
+++ b/shumate/vector/shumate-vector-expression-filter.c
@@ -36,6 +36,7 @@ typedef enum {
   EXPR_LT,
   EXPR_GE,
   EXPR_LE,
+  EXPR_CASE,
 } ExpressionType;
 
 struct _ShumateVectorExpressionFilter
@@ -149,6 +150,8 @@ shumate_vector_expression_filter_from_json_array (JsonArray *array, GError **err
       self->type = EXPR_LE;
       expect_exprs = 2;
     }
+  else if (g_strcmp0 ("case", op) == 0)
+    self->type = EXPR_CASE;
   else
     {
       g_set_error (error,
@@ -379,6 +382,35 @@ shumate_vector_expression_filter_eval (ShumateVectorExpression  *expr,
       shumate_vector_value_set_boolean (out, (number < number2) ^ inverted);
       return TRUE;
 
+    case EXPR_CASE:
+      for (int i = 0; i < n_expressions; i += 2)
+        {
+          if (!shumate_vector_expression_eval (expressions[i], scope, &value))
+            return FALSE;
+
+          if (i + 1 == n_expressions)
+            {
+              /* fallback value */
+              shumate_vector_value_copy (&value, out);
+              return TRUE;
+            }
+          else
+            {
+              gboolean bool_result;
+              shumate_vector_value_get_boolean (&value, &bool_result);
+              if (bool_result)
+                {
+                  if (!shumate_vector_expression_eval (expressions[i + 1], scope, &value))
+                    return FALSE;
+                  shumate_vector_value_copy (&value, out);
+                  return TRUE;
+                }
+            }
+        }
+
+      /* no case matched and there was no fallback */
+      return FALSE;
+
     default:
       g_assert_not_reached ();
     }
diff --git a/tests/vector-expression.c b/tests/vector-expression.c
index 2d2ae46..f9acc8f 100644
--- a/tests/vector-expression.c
+++ b/tests/vector-expression.c
@@ -167,6 +167,10 @@ test_vector_expression_basic_filter (void)
   g_assert_true  (filter ("[\"<=\", 10, 20]"));
   g_assert_true  (filter ("[\"<=\", 10, 10]"));
   g_assert_false (filter ("[\"<=\", 10, 5]"));
+
+  g_assert_true (filter ("[\"==\", [\"case\", true, 0, 1], 0]"));
+  g_assert_true (filter ("[\"==\", [\"case\", false, 0, 1], 1]"));
+  g_assert_true (filter ("[\"==\", [\"case\", false, 0, true, 2], 2]"));
 }
 
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]