diff --git a/bundle/src/main/java/dev/cel/bundle/CelEnvironmentExporter.java b/bundle/src/main/java/dev/cel/bundle/CelEnvironmentExporter.java index 4b26aca3..d303e052 100644 --- a/bundle/src/main/java/dev/cel/bundle/CelEnvironmentExporter.java +++ b/bundle/src/main/java/dev/cel/bundle/CelEnvironmentExporter.java @@ -119,7 +119,8 @@ public Builder addStandardExtensions(CelOptions options) { CelExtensions.getExtensionLibrary("math", options), CelExtensions.getExtensionLibrary("protos", options), CelExtensions.getExtensionLibrary("regex", options), - CelExtensions.getExtensionLibrary("sets", options)); + CelExtensions.getExtensionLibrary("sets", options), + CelExtensions.getExtensionLibrary("strings", options)); // TODO: add support for remaining standard extensions return this; } diff --git a/extensions/src/main/java/dev/cel/extensions/BUILD.bazel b/extensions/src/main/java/dev/cel/extensions/BUILD.bazel index 9a802d13..3b8b84bb 100644 --- a/extensions/src/main/java/dev/cel/extensions/BUILD.bazel +++ b/extensions/src/main/java/dev/cel/extensions/BUILD.bazel @@ -85,6 +85,7 @@ java_library( "//common/internal", "//common/types", "//compiler:compiler_builder", + "//extensions:extension_library", "//runtime", "//runtime:evaluation_exception_builder", "//runtime:function_binding", diff --git a/extensions/src/main/java/dev/cel/extensions/CelExtensions.java b/extensions/src/main/java/dev/cel/extensions/CelExtensions.java index bd5bf4b5..83bf3fa5 100644 --- a/extensions/src/main/java/dev/cel/extensions/CelExtensions.java +++ b/extensions/src/main/java/dev/cel/extensions/CelExtensions.java @@ -317,6 +317,8 @@ public static CelExtensionLibrary getE return CelRegexExtensions.library(); case "sets": return CelSetsExtensions.library(options); + case "strings": + return CelStringExtensions.library(); // TODO: add support for remaining standard extensions default: throw new IllegalArgumentException("Unknown standard extension '" + name + "'"); diff --git a/extensions/src/main/java/dev/cel/extensions/CelStringExtensions.java b/extensions/src/main/java/dev/cel/extensions/CelStringExtensions.java index 8e165b5e..37b2a368 100644 --- a/extensions/src/main/java/dev/cel/extensions/CelStringExtensions.java +++ b/extensions/src/main/java/dev/cel/extensions/CelStringExtensions.java @@ -14,6 +14,7 @@ package dev.cel.extensions; +import static com.google.common.collect.ImmutableSet.toImmutableSet; import static java.lang.Math.max; import static java.lang.Math.min; @@ -42,7 +43,8 @@ /** Internal implementation of CEL string extensions. */ @Immutable -public final class CelStringExtensions implements CelCompilerLibrary, CelRuntimeLibrary { +public final class CelStringExtensions + implements CelCompilerLibrary, CelRuntimeLibrary, CelExtensionLibrary.FeatureSet { /** Denotes the string extension function */ @SuppressWarnings({"unchecked"}) // Unchecked: Type-checker guarantees casting safety. @@ -250,6 +252,35 @@ String getFunction() { this.functions = ImmutableSet.copyOf(functions); } + private static final CelExtensionLibrary LIBRARY = + new CelExtensionLibrary() { + private final CelStringExtensions version0 = new CelStringExtensions(); + + @Override + public String name() { + return "strings"; + } + + @Override + public ImmutableSet versions() { + return ImmutableSet.of(version0); + } + }; + + static CelExtensionLibrary library() { + return LIBRARY; + } + + @Override + public int version() { + return 0; + } + + @Override + public ImmutableSet functions() { + return functions.stream().map(f -> f.functionDecl).collect(toImmutableSet()); + } + @Override public void setCheckerOptions(CelCheckerBuilder checkerBuilder) { functions.forEach(function -> checkerBuilder.addFunctionDeclarations(function.functionDecl)); diff --git a/extensions/src/test/java/dev/cel/extensions/CelStringExtensionsTest.java b/extensions/src/test/java/dev/cel/extensions/CelStringExtensionsTest.java index 45db9deb..6ea9b702 100644 --- a/extensions/src/test/java/dev/cel/extensions/CelStringExtensionsTest.java +++ b/extensions/src/test/java/dev/cel/extensions/CelStringExtensionsTest.java @@ -23,6 +23,8 @@ import com.google.testing.junit.testparameterinjector.TestParameterInjector; import com.google.testing.junit.testparameterinjector.TestParameters; import dev.cel.common.CelAbstractSyntaxTree; +import dev.cel.common.CelFunctionDecl; +import dev.cel.common.CelOptions; import dev.cel.common.CelValidationException; import dev.cel.common.types.SimpleType; import dev.cel.compiler.CelCompiler; @@ -54,6 +56,27 @@ public final class CelStringExtensionsTest { private static final CelRuntime RUNTIME = CelRuntimeFactory.standardCelRuntimeBuilder().addLibraries(CelExtensions.strings()).build(); + @Test + public void library() { + CelExtensionLibrary library = + CelExtensions.getExtensionLibrary("strings", CelOptions.DEFAULT); + assertThat(library.name()).isEqualTo("strings"); + assertThat(library.latest().version()).isEqualTo(0); + assertThat(library.version(0).functions().stream().map(CelFunctionDecl::name)) + .containsExactly( + "charAt", + "indexOf", + "join", + "lastIndexOf", + "lowerAscii", + "replace", + "split", + "substring", + "trim", + "upperAscii"); + assertThat(library.version(0).macros()).isEmpty(); + } + @Test @TestParameters("{string: 'abcd', beginIndex: 0, expectedResult: 'abcd'}") @TestParameters("{string: 'abcd', beginIndex: 1, expectedResult: 'bcd'}")