Skip to content

Commit

Permalink
ExtendedGrammar Case expression
Browse files Browse the repository at this point in the history
  • Loading branch information
nikoraes committed Oct 8, 2024
1 parent c598f7a commit d34fc73
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
35 changes: 35 additions & 0 deletions JexlNet.ExtendedGrammar/ExtendedGrammar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,13 @@ public ExtendedGrammar()
AddFunction("not", Not);
AddFunction("$not", Not);
AddTransform("not", Not);
// Case / Switch
AddFunction("case", Case);
AddFunction("$case", Case);
AddTransform("case", Case);
AddFunction("switch", Case);
AddFunction("$switch", Case);
AddTransform("switch", Case);
// ArrayAppend
AddFunction("append", ArrayAppend);
AddFunction("$append", ArrayAppend);
Expand Down Expand Up @@ -1093,6 +1100,34 @@ public static JsonNode Not(JsonNode input)
return null;
}

/// <summary>
/// Evaluates a list of predicates and returns the first result expression whose predicate is satisfied.
/// </summary>
/// <example><code>switch(expression, case1, result1, case2, result2, ..., default)</code><code>$switch(expression, case1, result1, case2, result2, ..., default)</code><code>expression|switch(case1, result1, case2, result2, ..., default)</code></example>
/// <returns>The result of the first case whose predicate is satisfied, or the default value if no case is satisfied</returns>
public static JsonNode Case(JsonNode[] args)
{
if (args.Length < 3) return null;

JsonNode expressionResult = args[0];

for (int i = 1; i < args.Length - 1; i += 2)
{
JsonNode caseResult = args[i];
if (JsonNode.DeepEquals(expressionResult, caseResult))
{
return args[i + 1];
}
}
// Return default
if (args.Length % 2 == 1)
{
return args[args.Length - 1];
}
// Return null if no default specified
return null;
}

/// <summary>
/// Returns a new array with the elements of the input array and the elements of the other array.
/// </summary>
Expand Down
12 changes: 12 additions & 0 deletions JexlNet.Test/ExtendedGrammar.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Text.Json;
using System.Text.Json.Nodes;
using Xunit.Sdk;

namespace JexlNet.Test;

Expand Down Expand Up @@ -257,6 +258,17 @@ public void Boolean(string expression, bool? expected)
Assert.Equal(expected, result?.GetValue<bool>());
}

[Theory]
[InlineData("2|case(1,'a',2,'b',3,'c')", "b")]
[InlineData("$case('bar','foo','a','bar','b','baz','c')", "b")]
[InlineData("'notfound'|case('bar','foo','a','bar','b','baz','c','b')", "b")]
public void Case(string expression, string expected)
{
var jexl = new Jexl(new ExtendedGrammar());
var result = jexl.Eval(expression);
Assert.Equal(expected, result?.ToString());
}

[Theory]
[InlineData("['foo', 'bar', 'baz'] | append('tek')")]
[InlineData("['foo', 'bar'] | append(['baz','tek'])")]
Expand Down

0 comments on commit d34fc73

Please sign in to comment.