Add support for case function
This commit is contained in:
@@ -12,6 +12,7 @@ export enum ErrorType {
|
||||
ErrorExceededMaxLength,
|
||||
ErrorTooFewParameters,
|
||||
ErrorTooManyParameters,
|
||||
ErrorEvenParameters,
|
||||
ErrorUnrecognizedContext,
|
||||
ErrorUnrecognizedFunction
|
||||
}
|
||||
@@ -42,6 +43,8 @@ function errorDescription(typ: ErrorType): string {
|
||||
return "Too few parameters supplied";
|
||||
case ErrorType.ErrorTooManyParameters:
|
||||
return "Too many parameters supplied";
|
||||
case ErrorType.ErrorEvenParameters:
|
||||
return "Even number of parameters supplied, requires an odd number of parameters";
|
||||
case ErrorType.ErrorUnrecognizedContext:
|
||||
return "Unrecognized named-value";
|
||||
case ErrorType.ErrorUnrecognizedFunction:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {ErrorType, ExpressionError} from "./errors.js";
|
||||
import {caseFunc} from "./funcs/case.js";
|
||||
import {contains} from "./funcs/contains.js";
|
||||
import {endswith} from "./funcs/endswith.js";
|
||||
import {format} from "./funcs/format.js";
|
||||
@@ -16,6 +17,7 @@ export type ParseContext = {
|
||||
};
|
||||
|
||||
export const wellKnownFunctions: {[name: string]: FunctionDefinition} = {
|
||||
case: caseFunc,
|
||||
contains: contains,
|
||||
endswith: endswith,
|
||||
format: format,
|
||||
@@ -53,4 +55,9 @@ export function validateFunction(context: ParseContext, identifier: Token, argCo
|
||||
if (argCount > f.maxArgs) {
|
||||
throw new ExpressionError(ErrorType.ErrorTooManyParameters, identifier);
|
||||
}
|
||||
|
||||
// case function requires an odd number of arguments
|
||||
if (name === "case" && argCount % 2 === 0) {
|
||||
throw new ExpressionError(ErrorType.ErrorEvenParameters, identifier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import {BooleanData, ExpressionData, Kind} from "../data";
|
||||
import {FunctionDefinition} from "./info";
|
||||
|
||||
export const caseFunc: FunctionDefinition = {
|
||||
name: "case",
|
||||
description:
|
||||
"`case( pred1, val1, pred2, val2, ..., default )`\n\nEvaluates predicates in order and returns the value corresponding to the first predicate that evaluates to `true`. If no predicate matches, returns the default value (the last argument).",
|
||||
minArgs: 3,
|
||||
maxArgs: Number.MAX_SAFE_INTEGER,
|
||||
call: (...args: ExpressionData[]): ExpressionData => {
|
||||
// Evaluate predicate-result pairs
|
||||
for (let i = 0; i < args.length - 1; i += 2) {
|
||||
const predicate = args[i];
|
||||
|
||||
// Predicate must be a boolean
|
||||
if (predicate.kind !== Kind.Boolean) {
|
||||
throw new Error("case predicate must evaluate to a boolean value");
|
||||
}
|
||||
|
||||
// If predicate is true, return the corresponding result
|
||||
if ((predicate as BooleanData).value) {
|
||||
return args[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
// No predicate matched, return default (last argument)
|
||||
return args[args.length - 1];
|
||||
}
|
||||
};
|
||||
Vendored
+157
@@ -0,0 +1,157 @@
|
||||
{
|
||||
"case": [
|
||||
{
|
||||
"expr": "case(true, 'first', 'default')",
|
||||
"result": { "kind": "String", "value": "first" }
|
||||
},
|
||||
{
|
||||
"expr": "case(false, 'first', 'default')",
|
||||
"result": { "kind": "String", "value": "default" }
|
||||
},
|
||||
{
|
||||
"expr": "case(true, 'first', false, 'second', 'default')",
|
||||
"result": { "kind": "String", "value": "first" }
|
||||
},
|
||||
{
|
||||
"expr": "case(false, 'first', true, 'second', 'default')",
|
||||
"result": { "kind": "String", "value": "second" }
|
||||
},
|
||||
{
|
||||
"expr": "case(false, 'first', false, 'second', 'default')",
|
||||
"result": { "kind": "String", "value": "default" }
|
||||
},
|
||||
{
|
||||
"expr": "case(1 == 1, 'equal', 'not equal')",
|
||||
"result": { "kind": "String", "value": "equal" }
|
||||
},
|
||||
{
|
||||
"expr": "case(1 == 2, 'equal', 'not equal')",
|
||||
"result": { "kind": "String", "value": "not equal" }
|
||||
},
|
||||
{
|
||||
"expr": "case(github.ref == 'refs/heads/main', 'main', github.event_name == 'pull_request', 'pr', 'other')",
|
||||
"contexts": {
|
||||
"github": {
|
||||
"ref": "refs/heads/main",
|
||||
"event_name": "push"
|
||||
}
|
||||
},
|
||||
"result": { "kind": "String", "value": "main" }
|
||||
},
|
||||
{
|
||||
"expr": "case(github.ref == 'refs/heads/main', 'main', github.event_name == 'pull_request', 'pr', 'other')",
|
||||
"contexts": {
|
||||
"github": {
|
||||
"ref": "refs/heads/develop",
|
||||
"event_name": "pull_request"
|
||||
}
|
||||
},
|
||||
"result": { "kind": "String", "value": "pr" }
|
||||
},
|
||||
{
|
||||
"expr": "case(github.ref == 'refs/heads/main', 'main', github.event_name == 'pull_request', 'pr', 'other')",
|
||||
"contexts": {
|
||||
"github": {
|
||||
"ref": "refs/heads/develop",
|
||||
"event_name": "push"
|
||||
}
|
||||
},
|
||||
"result": { "kind": "String", "value": "other" }
|
||||
},
|
||||
{
|
||||
"expr": "case(true, 123, 456)",
|
||||
"result": { "kind": "Number", "value": 123 }
|
||||
},
|
||||
{
|
||||
"expr": "case(false, 123, 456)",
|
||||
"result": { "kind": "Number", "value": 456 }
|
||||
},
|
||||
{
|
||||
"expr": "case(github.event == 'pull_request', 0, 1)",
|
||||
"contexts": {
|
||||
"github": {
|
||||
"event": "pull_request"
|
||||
}
|
||||
},
|
||||
"result": { "kind": "Number", "value": 0 }
|
||||
},
|
||||
{
|
||||
"expr": "case(false, 0, 1)",
|
||||
"result": { "kind": "Number", "value": 1 }
|
||||
},
|
||||
{
|
||||
"expr": "case(true, false, true)",
|
||||
"result": { "kind": "Boolean", "value": false }
|
||||
},
|
||||
{
|
||||
"expr": "case(false, false, true)",
|
||||
"result": { "kind": "Boolean", "value": true }
|
||||
},
|
||||
{
|
||||
"expr": "case(true, '', 'default')",
|
||||
"result": { "kind": "String", "value": "" }
|
||||
},
|
||||
{
|
||||
"expr": "case(false, 'first', '')",
|
||||
"result": { "kind": "String", "value": "" }
|
||||
},
|
||||
{
|
||||
"expr": "case(true, fromJSON('[1,2,3]'), 'default')",
|
||||
"result": { "kind": "Array", "value": [1, 2, 3] }
|
||||
},
|
||||
{
|
||||
"expr": "case(true, fromJSON('{\"key\":\"value\"}'), 'default')",
|
||||
"result": { "kind": "Object", "value": { "key": "value" } }
|
||||
},
|
||||
{
|
||||
"expr": "case(false, 'first', false, 'second', false, 'third', false, 'fourth', 'default')",
|
||||
"result": { "kind": "String", "value": "default" }
|
||||
},
|
||||
{
|
||||
"expr": "case(false, 'first', false, 'second', true, 'third', false, 'fourth', 'default')",
|
||||
"result": { "kind": "String", "value": "third" }
|
||||
},
|
||||
{
|
||||
"expr": "case('not a boolean', 'first', 'default')",
|
||||
"err": {
|
||||
"kind": "evaluation",
|
||||
"value": "case predicate must evaluate to a boolean value"
|
||||
}
|
||||
},
|
||||
{
|
||||
"expr": "case(1, 'first', 'default')",
|
||||
"err": {
|
||||
"kind": "evaluation",
|
||||
"value": "case predicate must evaluate to a boolean value"
|
||||
}
|
||||
},
|
||||
{
|
||||
"expr": "case(null, 'first', 'default')",
|
||||
"err": {
|
||||
"kind": "evaluation",
|
||||
"value": "case predicate must evaluate to a boolean value"
|
||||
}
|
||||
},
|
||||
{
|
||||
"expr": "case(fromJSON('[]'), 'first', 'default')",
|
||||
"err": {
|
||||
"kind": "evaluation",
|
||||
"value": "case predicate must evaluate to a boolean value"
|
||||
}
|
||||
},
|
||||
{
|
||||
"expr": "case(fromJSON('{}'), 'first', 'default')",
|
||||
"err": {
|
||||
"kind": "evaluation",
|
||||
"value": "case predicate must evaluate to a boolean value"
|
||||
}
|
||||
},
|
||||
{
|
||||
"expr": "case(true, 'first', false, 'second')",
|
||||
"err": {
|
||||
"kind": "parsing",
|
||||
"value": "Even number of parameters supplied, requires an odd number of parameters: 'case'. Located at position 1 within expression: case(true, 'first', false, 'second')"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user