Skip to content

Commit 4c34530

Browse files
l46kokcopybara-github
authored andcommitted
Add string to boolean conversion function in the standard definition
PiperOrigin-RevId: 658882554
1 parent ea16dc4 commit 4c34530

5 files changed

Lines changed: 66 additions & 2 deletions

File tree

checker/src/main/java/dev/cel/checker/Standard.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,9 @@ private static ImmutableList<CelFunctionDecl> coreFunctionDeclarations() {
475475
CelFunctionDecl.newFunctionDeclaration(
476476
Function.BOOL.getFunction(),
477477
CelOverloadDecl.newGlobalOverload(
478-
"bool_to_bool", "type conversion (identity)", SimpleType.BOOL, SimpleType.BOOL)));
478+
"bool_to_bool", "type conversion (identity)", SimpleType.BOOL, SimpleType.BOOL),
479+
CelOverloadDecl.newGlobalOverload(
480+
"string_to_bool", "type conversion", SimpleType.BOOL, SimpleType.STRING)));
479481

480482
// String functions
481483
celFunctionDeclBuilder.add(

checker/src/test/resources/standardEnvDump.baseline

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ declare _||_ {
144144
declare bool {
145145
value type(bool)
146146
function bool_to_bool (bool) -> bool
147+
function string_to_bool (string) -> bool
147148
}
148149
declare bytes {
149150
value type(bytes)

runtime/src/main/java/dev/cel/runtime/StandardFunctions.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,33 @@ public static void addNonInlined(
156156
private static void addBoolFunctions(Registrar registrar) {
157157
// Identity
158158
registrar.add("bool_to_bool", Boolean.class, (Boolean x) -> x);
159+
// Conversion function
160+
registrar.add(
161+
"string_to_bool",
162+
String.class,
163+
(String str) -> {
164+
// Note: this is a bit less permissive than what cel-go allows (it accepts '1', 't').
165+
switch (str) {
166+
case "true":
167+
case "TRUE":
168+
case "True":
169+
case "t":
170+
case "1":
171+
return true;
172+
case "false":
173+
case "FALSE":
174+
case "False":
175+
case "f":
176+
case "0":
177+
return false;
178+
default:
179+
throw new InterpreterException.Builder(
180+
"Type conversion error from 'string' to 'bool': [%s]", str)
181+
.setErrorCode(CelErrorCode.BAD_FORMAT)
182+
.build();
183+
}
184+
});
185+
159186
// The conditional, logical_or, logical_and, and not_strictly_false functions are special-cased.
160187
registrar.add("logical_not", Boolean.class, (Boolean x) -> !x);
161188

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,26 @@
11
Source: bool(true)
22
=====>
33
bindings: {}
4-
result: true
4+
result: true
5+
6+
Source: bool('true') && bool('TRUE') && bool('True') && bool('t') && bool('1')
7+
=====>
8+
bindings: {}
9+
result: true
10+
11+
Source: bool('false') || bool('FALSE') || bool('False') || bool('f') || bool('0')
12+
=====>
13+
bindings: {}
14+
result: false
15+
16+
Source: bool('TrUe')
17+
=====>
18+
bindings: {}
19+
error: evaluation error: Type conversion error from 'string' to 'bool': [TrUe]
20+
error_code: BAD_FORMAT
21+
22+
Source: bool('FaLsE')
23+
=====>
24+
bindings: {}
25+
error: evaluation error: Type conversion error from 'string' to 'bool': [FaLsE]
26+
error_code: BAD_FORMAT

testing/src/main/java/dev/cel/testing/BaseInterpreterTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1568,6 +1568,18 @@ public void bytes() throws Exception {
15681568
public void boolConversions() throws Exception {
15691569
source = "bool(true)";
15701570
runTest(Activation.EMPTY); // Identity
1571+
1572+
source = "bool('true') && bool('TRUE') && bool('True') && bool('t') && bool('1')";
1573+
runTest(Activation.EMPTY); // result is true
1574+
1575+
source = "bool('false') || bool('FALSE') || bool('False') || bool('f') || bool('0')";
1576+
runTest(Activation.EMPTY); // result is false
1577+
1578+
source = "bool('TrUe')";
1579+
runTest(Activation.EMPTY); // exception
1580+
1581+
source = "bool('FaLsE')";
1582+
runTest(Activation.EMPTY); // exception
15711583
}
15721584

15731585
@Test

0 commit comments

Comments
 (0)