diff --git a/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/language/functions/AwsPartition.java b/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/language/functions/AwsPartition.java index a32c0359c61..c04116f7ed3 100644 --- a/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/language/functions/AwsPartition.java +++ b/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/language/functions/AwsPartition.java @@ -18,7 +18,7 @@ import software.amazon.smithy.rulesengine.language.evaluation.type.Type; import software.amazon.smithy.rulesengine.language.evaluation.value.Value; import software.amazon.smithy.rulesengine.language.syntax.Identifier; -import software.amazon.smithy.rulesengine.language.syntax.expressions.Expression; +import software.amazon.smithy.rulesengine.language.syntax.ToExpression; import software.amazon.smithy.rulesengine.language.syntax.expressions.ExpressionVisitor; import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.FunctionDefinition; import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.FunctionNode; @@ -74,7 +74,7 @@ public static Definition getDefinition() { * @param arg1 the region to retrieve partition information from. * @return The resulting {@link AwsPartition} function. */ - public static AwsPartition ofExpressions(Expression arg1) { + public static AwsPartition ofExpressions(ToExpression arg1) { return DEFINITION.createFunction(FunctionNode.ofExpressions(ID, arg1)); } diff --git a/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/language/functions/IsVirtualHostableS3Bucket.java b/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/language/functions/IsVirtualHostableS3Bucket.java index deb3f78695d..ed71181cabe 100644 --- a/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/language/functions/IsVirtualHostableS3Bucket.java +++ b/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/language/functions/IsVirtualHostableS3Bucket.java @@ -10,6 +10,7 @@ import java.util.regex.Pattern; import software.amazon.smithy.rulesengine.language.evaluation.type.Type; import software.amazon.smithy.rulesengine.language.evaluation.value.Value; +import software.amazon.smithy.rulesengine.language.syntax.ToExpression; import software.amazon.smithy.rulesengine.language.syntax.expressions.Expression; import software.amazon.smithy.rulesengine.language.syntax.expressions.ExpressionVisitor; import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.FunctionDefinition; @@ -45,10 +46,22 @@ public static Definition getDefinition() { * @param arg2 whether to allow subdomains. * @return The resulting {@link IsVirtualHostableS3Bucket} function. */ - public static IsVirtualHostableS3Bucket ofExpressions(Expression arg1, Expression arg2) { + public static IsVirtualHostableS3Bucket ofExpressions(ToExpression arg1, ToExpression arg2) { return DEFINITION.createFunction(FunctionNode.ofExpressions(ID, arg1, arg2)); } + + /** + * Creates a {@link IsVirtualHostableS3Bucket} function from the given expressions. + * + * @param arg1 the value to check. + * @param arg2 whether to allow subdomains. + * @return The resulting {@link IsVirtualHostableS3Bucket} function. + */ + public static IsVirtualHostableS3Bucket ofExpressions(ToExpression arg1, boolean arg2) { + return ofExpressions(arg1, Expression.of(arg2)); + } + @Override public T accept(ExpressionVisitor visitor) { return visitor.visitLibraryFunction(DEFINITION, getArguments()); diff --git a/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/language/functions/ParseArn.java b/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/language/functions/ParseArn.java index 3a910080adb..5161a7bc8cd 100644 --- a/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/language/functions/ParseArn.java +++ b/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/language/functions/ParseArn.java @@ -14,7 +14,7 @@ import software.amazon.smithy.rulesengine.language.evaluation.type.Type; import software.amazon.smithy.rulesengine.language.evaluation.value.Value; import software.amazon.smithy.rulesengine.language.syntax.Identifier; -import software.amazon.smithy.rulesengine.language.syntax.expressions.Expression; +import software.amazon.smithy.rulesengine.language.syntax.ToExpression; import software.amazon.smithy.rulesengine.language.syntax.expressions.ExpressionVisitor; import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.FunctionDefinition; import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.FunctionNode; @@ -56,7 +56,7 @@ public static Definition getDefinition() { * @param arg1 the ARN to parse. * @return The resulting {@link ParseArn} function. */ - public static ParseArn ofExpressions(Expression arg1) { + public static ParseArn ofExpressions(ToExpression arg1) { return DEFINITION.createFunction(FunctionNode.ofExpressions(ID, arg1)); } diff --git a/smithy-aws-endpoints/src/test/java/software/amazon/smithy/rulesengine/aws/language/functions/FunctionsTest.java b/smithy-aws-endpoints/src/test/java/software/amazon/smithy/rulesengine/aws/language/functions/FunctionsTest.java index 64bb064eaaf..cbc88262529 100644 --- a/smithy-aws-endpoints/src/test/java/software/amazon/smithy/rulesengine/aws/language/functions/FunctionsTest.java +++ b/smithy-aws-endpoints/src/test/java/software/amazon/smithy/rulesengine/aws/language/functions/FunctionsTest.java @@ -16,8 +16,12 @@ public void awsPartitionOfExpression() { @Test public void isVirtualHostableS3BucketOfExpression() { IsVirtualHostableS3Bucket function = IsVirtualHostableS3Bucket.ofExpressions( - Expression.of("foobar"), Expression.of(true)); + Expression.of("foobar"), true); assertThat(function, instanceOf(IsVirtualHostableS3Bucket.class)); + + IsVirtualHostableS3Bucket function2 = IsVirtualHostableS3Bucket.ofExpressions( + Expression.of("foobar"), Expression.of(true)); + assertThat(function2, instanceOf(IsVirtualHostableS3Bucket.class)); } @Test diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/SyntaxElement.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/SyntaxElement.java new file mode 100644 index 00000000000..9fbc31a6b6b --- /dev/null +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/SyntaxElement.java @@ -0,0 +1,124 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package software.amazon.smithy.rulesengine.language.syntax; + +import software.amazon.smithy.rulesengine.language.syntax.expressions.Expression; +import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.BooleanEquals; +import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.GetAttr; +import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.IsSet; +import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.IsValidHostLabel; +import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.Not; +import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.ParseUrl; +import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.StringEquals; +import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.Substring; +import software.amazon.smithy.rulesengine.language.syntax.rule.Condition; +import software.amazon.smithy.utils.SmithyInternalApi; + +/** + * A class that is coercible into {@link Condition}s and {@link Expression}s for + * use in composing rule-sets in code. + */ +@SmithyInternalApi +public abstract class SyntaxElement implements ToCondition, ToExpression { + /** + * Returns a BooleanEquals expression comparing this expression to the provided boolean value. + * + * @param value the value to compare against. + * @return the {@link BooleanEquals} function. + */ + public final BooleanEquals booleanEqual(boolean value) { + return BooleanEquals.ofExpressions(toExpression(), Expression.of(value)); + } + + /** + * Returns a StringEquals function of this expression and the given string value. + * + * @param value the string value to compare this expression to. + * @return the {@link StringEquals} function. + */ + public final StringEquals stringEqual(String value) { + return StringEquals.ofExpressions(toExpression(), Expression.of(value)); + } + + /** + * Returns a GetAttr function containing the given path string. + * + * @param path the path. + * @return the {@link GetAttr} function. + */ + public final GetAttr getAttr(String path) { + return GetAttr.ofExpressions(toExpression(), path); + } + + /** + * Returns a GetAttr function containing the given identifier. + * + * @param path the path. + * @return the {@link GetAttr} function. + */ + public final GetAttr getAttr(Identifier path) { + return GetAttr.ofExpressions(toExpression(), path.toString()); + } + + /** + * Returns an IsSet expression for this instance. + * + * @return the {@link IsSet} function. + */ + public final IsSet isSet() { + return IsSet.ofExpressions(toExpression()); + } + + /** + * Returns an isValidHostLabel expression of this expression. + * + * @param allowDots whether the UTF-8 {@code .} is considered valid within a host label. + * @return the {@link IsValidHostLabel} function. + */ + public final IsValidHostLabel isValidHostLabel(boolean allowDots) { + return IsValidHostLabel.ofExpressions(toExpression(), allowDots); + } + + /** + * Returns a Not expression of this instance. + * + * @return the {@link Not} function. + */ + public final Not not() { + return Not.ofExpressions(toExpression()); + } + + /** + * Returns a parseUrl expression of this expression. + * + * @return the {@link ParseUrl} function. + */ + public final ParseUrl parseUrl() { + return ParseUrl.ofExpressions(toExpression()); + } + + /** + * Returns a Substring expression of this expression. + * + * @param startIndex the starting index of the string. + * @param stopIndex the ending index of the string. + * @param reverse whether the indexing is should start from end of the string to start. + * @return the {@link Substring} function. + */ + public final Substring substring(int startIndex, int stopIndex, boolean reverse) { + return Substring.ofExpressions(toExpression(), startIndex, stopIndex, reverse); + } + + /** + * Converts this expression to a string template. + * By default, this implementation returns a {@link RuntimeException}. + * + * @return the String template. + */ + public String template() { + throw new RuntimeException(String.format("cannot convert %s to a string template", this)); + } +} diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/ToCondition.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/ToCondition.java new file mode 100644 index 00000000000..7e59d2e6ab4 --- /dev/null +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/ToCondition.java @@ -0,0 +1,42 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package software.amazon.smithy.rulesengine.language.syntax; + +import software.amazon.smithy.rulesengine.language.syntax.rule.Condition; +import software.amazon.smithy.utils.SmithyInternalApi; + +/** + * Supplies functionality to be coercible into {@link Condition}s for + * use in composing rule-sets in code. + */ +@SmithyInternalApi +public interface ToCondition { + /** + * Convert this into a condition builder for compositional use. + * + * @return the condition builder. + */ + Condition.Builder toConditionBuilder(); + + /** + * Convert this into a condition. + * + * @return the condition. + */ + default Condition toCondition() { + return toConditionBuilder().build(); + } + + /** + * Converts this function into a condition which stores the output in the named result. + * + * @param result the name of the result parameter. + * @return the function as a condition. + */ + default Condition toCondition(String result) { + return toConditionBuilder().result(result).build(); + } +} diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/ToExpression.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/ToExpression.java new file mode 100644 index 00000000000..45a2b9ae249 --- /dev/null +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/ToExpression.java @@ -0,0 +1,23 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package software.amazon.smithy.rulesengine.language.syntax; + +import software.amazon.smithy.rulesengine.language.syntax.expressions.Expression; +import software.amazon.smithy.utils.SmithyInternalApi; + +/** + * Supplies functionality to be coercible into {@link Expression}s for + * use in composing rule-sets in code. + */ +@SmithyInternalApi +public interface ToExpression { + /** + * Convert this into an expression. + * + * @return the expression. + */ + Expression toExpression(); +} diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/Expression.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/Expression.java index ec20b80031b..55b66e3b354 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/Expression.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/Expression.java @@ -21,10 +21,11 @@ import software.amazon.smithy.rulesengine.language.evaluation.TypeCheck; import software.amazon.smithy.rulesengine.language.evaluation.type.Type; import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.SyntaxElement; import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.FunctionNode; import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.GetAttr; -import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.Not; import software.amazon.smithy.rulesengine.language.syntax.expressions.literal.Literal; +import software.amazon.smithy.rulesengine.language.syntax.rule.Condition; import software.amazon.smithy.utils.SmithyUnstableApi; /** @@ -33,7 +34,7 @@ * Expressions are the fundamental building block of the rule language. */ @SmithyUnstableApi -public abstract class Expression implements FromSourceLocation, ToNode, TypeCheck { +public abstract class Expression extends SyntaxElement implements FromSourceLocation, ToNode, TypeCheck { private final SourceLocation sourceLocation; private Type cachedType; @@ -65,15 +66,6 @@ public static Literal of(String value) { return getLiteral(StringNode.from(value)); } - /** - * Negates the current expression. - * - * @return the negated expression. - */ - public Expression not() { - return Not.ofExpressions(this); - } - /** * Constructs an expression from the provided {@link Node}. * @@ -160,14 +152,14 @@ public Type type() { return cachedType; } - /** - * Converts this expression to a string template. By default, - * this implementation returns a {@link RuntimeException}. - * - * @return the string template. - */ - public String getTemplate() { - throw new RuntimeException(String.format("Cannot convert `%s` to a string template.", this)); + @Override + public Condition.Builder toConditionBuilder() { + return Condition.builder().fn(this); + } + + @Override + public Expression toExpression() { + return this; } @Override diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/Reference.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/Reference.java index 31866b592f9..b670a7f8d0b 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/Reference.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/Reference.java @@ -44,7 +44,7 @@ public Identifier getName() { } @Override - public String getTemplate() { + public String template() { return String.format("{%s}", name); } diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/BooleanEquals.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/BooleanEquals.java index 19a743fd9f2..985050af71a 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/BooleanEquals.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/BooleanEquals.java @@ -9,6 +9,7 @@ import java.util.List; import software.amazon.smithy.rulesengine.language.evaluation.type.Type; import software.amazon.smithy.rulesengine.language.evaluation.value.Value; +import software.amazon.smithy.rulesengine.language.syntax.ToExpression; import software.amazon.smithy.rulesengine.language.syntax.expressions.Expression; import software.amazon.smithy.rulesengine.language.syntax.expressions.ExpressionVisitor; import software.amazon.smithy.utils.SmithyUnstableApi; @@ -41,10 +42,21 @@ public static Definition getDefinition() { * @param arg2 the second argument to compare. * @return The resulting {@link BooleanEquals} function. */ - public static BooleanEquals ofExpressions(Expression arg1, Expression arg2) { + public static BooleanEquals ofExpressions(ToExpression arg1, ToExpression arg2) { return DEFINITION.createFunction(FunctionNode.ofExpressions(ID, arg1, arg2)); } + /** + * Creates a {@link BooleanEquals} function from the given expressions. + * + * @param arg1 the first argument to compare. + * @param arg2 the second argument to compare. + * @return The resulting {@link BooleanEquals} function. + */ + public static BooleanEquals ofExpressions(ToExpression arg1, boolean arg2) { + return ofExpressions(arg1, Expression.of(arg2)); + } + @Override public R accept(ExpressionVisitor visitor) { return visitor.visitBoolEquals(functionNode.getArguments().get(0), functionNode.getArguments().get(1)); diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/FunctionNode.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/FunctionNode.java index d2895fdcf88..8d32443d472 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/FunctionNode.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/FunctionNode.java @@ -20,6 +20,7 @@ import software.amazon.smithy.rulesengine.language.EndpointRuleSet; import software.amazon.smithy.rulesengine.language.RulesComponentBuilder; import software.amazon.smithy.rulesengine.language.error.RuleError; +import software.amazon.smithy.rulesengine.language.syntax.ToExpression; import software.amazon.smithy.rulesengine.language.syntax.expressions.Expression; import software.amazon.smithy.utils.BuilderRef; import software.amazon.smithy.utils.SmithyBuilder; @@ -34,14 +35,16 @@ public final class FunctionNode implements FromSourceLocation, ToNode, ToSmithyB private static final String ARGV = "argv"; private static final String FN = "fn"; + private final List arguments = new ArrayList<>(); private final StringNode name; private final SourceLocation sourceLocation; - private final List arguments; FunctionNode(Builder builder) { - this.name = SmithyBuilder.requiredState("functionName", builder.function); - this.sourceLocation = builder.getSourceLocation(); - this.arguments = builder.argv.copy(); + for (ToExpression expression : builder.argv.get()) { + arguments.add(expression.toExpression()); + } + name = SmithyBuilder.requiredState("functionName", builder.function); + sourceLocation = builder.getSourceLocation(); } /** @@ -51,7 +54,7 @@ public final class FunctionNode implements FromSourceLocation, ToNode, ToSmithyB * @param arguments zero or more expressions as arguments to the function. * @return the {@link FunctionNode}. */ - public static FunctionNode ofExpressions(String functionName, Expression... arguments) { + public static FunctionNode ofExpressions(String functionName, ToExpression... arguments) { return ofExpressions(functionName, SourceLocation.none(), arguments); } @@ -66,7 +69,7 @@ public static FunctionNode ofExpressions(String functionName, Expression... argu public static FunctionNode ofExpressions( String functionName, FromSourceLocation sourceLocation, - Expression... arguments + ToExpression... arguments ) { return builder() .sourceLocation(sourceLocation) @@ -183,13 +186,13 @@ public int hashCode() { */ public static final class Builder extends RulesComponentBuilder { private StringNode function; - private final BuilderRef> argv = BuilderRef.forList(); + private final BuilderRef> argv = BuilderRef.forList(); private Builder() { super(SourceLocation.none()); } - public Builder arguments(List argv) { + public Builder arguments(List argv) { this.argv.clear(); this.argv.get().addAll(argv); return this; diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/GetAttr.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/GetAttr.java index 6331865f496..6dd674ba344 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/GetAttr.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/GetAttr.java @@ -23,6 +23,7 @@ import software.amazon.smithy.rulesengine.language.evaluation.type.Type; import software.amazon.smithy.rulesengine.language.evaluation.value.Value; import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.ToExpression; import software.amazon.smithy.rulesengine.language.syntax.expressions.Expression; import software.amazon.smithy.rulesengine.language.syntax.expressions.ExpressionVisitor; import software.amazon.smithy.rulesengine.language.syntax.expressions.Reference; @@ -64,10 +65,21 @@ public static Definition getDefinition() { * @param arg2 the path to extract. * @return The resulting {@link GetAttr} function. */ - public static GetAttr ofExpressions(Expression arg1, Expression arg2) { + public static GetAttr ofExpressions(ToExpression arg1, ToExpression arg2) { return DEFINITION.createFunction(FunctionNode.ofExpressions(ID, arg1, arg2)); } + /** + * Creates a {@link GetAttr} function from the given expressions. + * + * @param arg1 the argument to extract from. + * @param arg2 the path to extract. + * @return The resulting {@link GetAttr} function. + */ + public static GetAttr ofExpressions(ToExpression arg1, String arg2) { + return ofExpressions(arg1, Expression.of(arg2)); + } + /** * Parses the path argument to getAttr. * @@ -157,7 +169,7 @@ protected Type typeCheckLocal(Scope scope) { } @Override - public String getTemplate() { + public String template() { String targetString = ((Reference) target).getName().toString(); return "{" + targetString + "#" + unparsedPath + "}"; } diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/IsSet.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/IsSet.java index 531035baa55..133b7b58a77 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/IsSet.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/IsSet.java @@ -10,6 +10,7 @@ import software.amazon.smithy.rulesengine.language.evaluation.Scope; import software.amazon.smithy.rulesengine.language.evaluation.type.Type; import software.amazon.smithy.rulesengine.language.evaluation.value.Value; +import software.amazon.smithy.rulesengine.language.syntax.ToExpression; import software.amazon.smithy.rulesengine.language.syntax.expressions.Expression; import software.amazon.smithy.rulesengine.language.syntax.expressions.ExpressionVisitor; import software.amazon.smithy.rulesengine.language.syntax.expressions.Reference; @@ -36,6 +37,16 @@ public static Definition getDefinition() { return DEFINITION; } + /** + * Creates a {@link IsSet} function from the given expressions. + * + * @param arg1 the expression to negate. + * @return The resulting {@link IsSet} function. + */ + public static IsSet ofExpressions(ToExpression arg1) { + return DEFINITION.createFunction(FunctionNode.ofExpressions(ID, arg1)); + } + @Override public R accept(ExpressionVisitor visitor) { return visitor.visitIsSet(expectOneArgument()); diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/IsValidHostLabel.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/IsValidHostLabel.java index 053f738efd2..41074339ac8 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/IsValidHostLabel.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/IsValidHostLabel.java @@ -9,6 +9,7 @@ import java.util.List; import software.amazon.smithy.rulesengine.language.evaluation.type.Type; import software.amazon.smithy.rulesengine.language.evaluation.value.Value; +import software.amazon.smithy.rulesengine.language.syntax.ToExpression; import software.amazon.smithy.rulesengine.language.syntax.expressions.Expression; import software.amazon.smithy.rulesengine.language.syntax.expressions.ExpressionVisitor; import software.amazon.smithy.utils.SmithyUnstableApi; @@ -41,10 +42,21 @@ public static Definition getDefinition() { * @param arg2 whether to allow subdomains. * @return The resulting {@link IsValidHostLabel} function. */ - public static IsValidHostLabel ofExpressions(Expression arg1, Expression arg2) { + public static IsValidHostLabel ofExpressions(ToExpression arg1, ToExpression arg2) { return DEFINITION.createFunction(FunctionNode.ofExpressions(ID, arg1, arg2)); } + /** + * Creates a {@link IsValidHostLabel} function from the given expressions. + * + * @param arg1 the value to check. + * @param arg2 whether to allow subdomains. + * @return The resulting {@link IsValidHostLabel} function. + */ + public static IsValidHostLabel ofExpressions(ToExpression arg1, boolean arg2) { + return ofExpressions(arg1, Expression.of(arg2)); + } + @Override public T accept(ExpressionVisitor visitor) { return visitor.visitLibraryFunction(DEFINITION, getArguments()); diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/Not.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/Not.java index dc8176fb299..f77271e4de7 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/Not.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/Not.java @@ -12,7 +12,7 @@ import software.amazon.smithy.rulesengine.language.evaluation.Scope; import software.amazon.smithy.rulesengine.language.evaluation.type.Type; import software.amazon.smithy.rulesengine.language.evaluation.value.Value; -import software.amazon.smithy.rulesengine.language.syntax.expressions.Expression; +import software.amazon.smithy.rulesengine.language.syntax.ToExpression; import software.amazon.smithy.rulesengine.language.syntax.expressions.ExpressionVisitor; import software.amazon.smithy.utils.SmithyUnstableApi; @@ -40,7 +40,7 @@ public static Definition getDefinition() { * @param arg1 the expression to negate. * @return The resulting {@link Not} function. */ - public static Not ofExpressions(Expression arg1) { + public static Not ofExpressions(ToExpression arg1) { return DEFINITION.createFunction(FunctionNode.ofExpressions(ID, arg1)); } diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/ParseUrl.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/ParseUrl.java index 739699eaf5b..fc45f83a16d 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/ParseUrl.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/ParseUrl.java @@ -14,7 +14,7 @@ import software.amazon.smithy.rulesengine.language.evaluation.type.Type; import software.amazon.smithy.rulesengine.language.evaluation.value.Value; import software.amazon.smithy.rulesengine.language.syntax.Identifier; -import software.amazon.smithy.rulesengine.language.syntax.expressions.Expression; +import software.amazon.smithy.rulesengine.language.syntax.ToExpression; import software.amazon.smithy.rulesengine.language.syntax.expressions.ExpressionVisitor; import software.amazon.smithy.utils.SmithyUnstableApi; import software.amazon.smithy.utils.StringUtils; @@ -51,7 +51,7 @@ public static Definition getDefinition() { * @param arg1 the URI to parse. * @return The resulting {@link ParseUrl} function. */ - public static ParseUrl ofExpressions(Expression arg1) { + public static ParseUrl ofExpressions(ToExpression arg1) { return DEFINITION.createFunction(FunctionNode.ofExpressions(ID, arg1)); } diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/StringEquals.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/StringEquals.java index 4153df9c8fd..c2766c3cfb2 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/StringEquals.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/StringEquals.java @@ -9,6 +9,7 @@ import java.util.List; import software.amazon.smithy.rulesengine.language.evaluation.type.Type; import software.amazon.smithy.rulesengine.language.evaluation.value.Value; +import software.amazon.smithy.rulesengine.language.syntax.ToExpression; import software.amazon.smithy.rulesengine.language.syntax.expressions.Expression; import software.amazon.smithy.rulesengine.language.syntax.expressions.ExpressionVisitor; import software.amazon.smithy.utils.SmithyUnstableApi; @@ -41,10 +42,21 @@ public static Definition getDefinition() { * @param arg2 the second argument to compare. * @return The resulting {@link StringEquals} function. */ - public static StringEquals ofExpressions(Expression arg1, Expression arg2) { + public static StringEquals ofExpressions(ToExpression arg1, ToExpression arg2) { return DEFINITION.createFunction(FunctionNode.ofExpressions(ID, arg1, arg2)); } + /** + * Creates a {@link StringEquals} function from the given expressions. + * + * @param arg1 the first argument to compare. + * @param arg2 the second argument to compare. + * @return The resulting {@link StringEquals} function. + */ + public static StringEquals ofExpressions(ToExpression arg1, String arg2) { + return ofExpressions(arg1, Expression.of(arg2)); + } + @Override public R accept(ExpressionVisitor visitor) { return visitor.visitStringEquals(functionNode.getArguments().get(0), functionNode.getArguments().get(1)); diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/Substring.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/Substring.java index 45f2b147b9d..ed5369dc6a7 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/Substring.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/Substring.java @@ -9,6 +9,7 @@ import java.util.List; import software.amazon.smithy.rulesengine.language.evaluation.type.Type; import software.amazon.smithy.rulesengine.language.evaluation.value.Value; +import software.amazon.smithy.rulesengine.language.syntax.ToExpression; import software.amazon.smithy.rulesengine.language.syntax.expressions.Expression; import software.amazon.smithy.rulesengine.language.syntax.expressions.ExpressionVisitor; import software.amazon.smithy.utils.SmithyUnstableApi; @@ -37,14 +38,32 @@ public static Definition getDefinition() { /** * Creates a {@link Substring} function from the given expressions. * - * @param arg1 the string to extract from. - * @param arg2 the starting index. - * @param arg3 the ending index. - * @param arg4 the reverse order argument. + * @param expression the string to extract from. + * @param startIndex the starting index. + * @param stopIndex the ending index. + * @param reverse the reverse order argument. * @return The resulting {@link Substring} function. */ - public static Substring ofExpressions(Expression arg1, Expression arg2, Expression arg3, Expression arg4) { - return DEFINITION.createFunction(FunctionNode.ofExpressions(ID, arg1, arg2, arg3, arg4)); + public static Substring ofExpressions( + ToExpression expression, + ToExpression startIndex, + ToExpression stopIndex, + ToExpression reverse + ) { + return DEFINITION.createFunction(FunctionNode.ofExpressions(ID, expression, startIndex, stopIndex, reverse)); + } + + /** + * Creates a {@link Substring} function from the given expressions. + * + * @param expression the string to extract from. + * @param startIndex the starting index. + * @param stopIndex the ending index. + * @param reverse the reverse order argument. + * @return The resulting {@link Substring} function. + */ + public static Substring ofExpressions(ToExpression expression, int startIndex, int stopIndex, boolean reverse) { + return ofExpressions(expression, Expression.of(startIndex), Expression.of(stopIndex), Expression.of(reverse)); } @Override diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/UriEncode.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/UriEncode.java index 68946dcacae..8926bb074b9 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/UriEncode.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expressions/functions/UriEncode.java @@ -12,7 +12,7 @@ import java.util.Map; import software.amazon.smithy.rulesengine.language.evaluation.type.Type; import software.amazon.smithy.rulesengine.language.evaluation.value.Value; -import software.amazon.smithy.rulesengine.language.syntax.expressions.Expression; +import software.amazon.smithy.rulesengine.language.syntax.ToExpression; import software.amazon.smithy.rulesengine.language.syntax.expressions.ExpressionVisitor; import software.amazon.smithy.utils.MapUtils; import software.amazon.smithy.utils.SmithyUnstableApi; @@ -44,7 +44,7 @@ public static Definition getDefinition() { * @param arg1 the value to URI encode. * @return The resulting {@link UriEncode} function. */ - public static UriEncode ofExpressions(Expression arg1) { + public static UriEncode ofExpressions(ToExpression arg1) { return DEFINITION.createFunction(FunctionNode.ofExpressions(ID, arg1)); } diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/Parameter.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/Parameter.java index 6764c014991..322f41fa05d 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/Parameter.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/Parameter.java @@ -19,7 +19,9 @@ import software.amazon.smithy.rulesengine.language.evaluation.type.Type; import software.amazon.smithy.rulesengine.language.evaluation.value.Value; import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.SyntaxElement; import software.amazon.smithy.rulesengine.language.syntax.expressions.Expression; +import software.amazon.smithy.rulesengine.language.syntax.rule.Condition; import software.amazon.smithy.utils.ListUtils; import software.amazon.smithy.utils.SmithyBuilder; import software.amazon.smithy.utils.SmithyUnstableApi; @@ -29,7 +31,7 @@ * A rule-set parameter, representing a value usable in conditions and rules. */ @SmithyUnstableApi -public final class Parameter implements ToSmithyBuilder, FromSourceLocation, ToNode { +public final class Parameter extends SyntaxElement implements ToSmithyBuilder, FromSourceLocation, ToNode { public static final String TYPE = "type"; public static final String DEPRECATED = "deprecated"; public static final String DOCUMENTATION = "documentation"; @@ -215,11 +217,12 @@ public Optional getDefault() { return Optional.ofNullable(defaultValue); } - /** - * Provides a reference to this parameter as an expression. - * - * @return a reference to the parameter. - */ + @Override + public Condition.Builder toConditionBuilder() { + return Condition.builder().fn(toExpression()); + } + + @Override public Expression toExpression() { return Expression.getReference(name, SourceLocation.none()); } diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/Condition.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/Condition.java index 570a6e7ffc8..d33fff66cb8 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/Condition.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/Condition.java @@ -19,6 +19,7 @@ import software.amazon.smithy.rulesengine.language.evaluation.TypeCheck; import software.amazon.smithy.rulesengine.language.evaluation.type.Type; import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.SyntaxElement; import software.amazon.smithy.rulesengine.language.syntax.expressions.Expression; import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.FunctionNode; import software.amazon.smithy.utils.SmithyBuilder; @@ -29,7 +30,7 @@ * Can assign the results of functions to new parameters within the current scope. */ @SmithyUnstableApi -public final class Condition implements TypeCheck, FromSourceLocation, ToNode { +public final class Condition extends SyntaxElement implements TypeCheck, FromSourceLocation, ToNode { public static final String ASSIGN = "assign"; private final Expression function; private final Identifier result; @@ -90,12 +91,17 @@ public Expression getFunction() { return function; } - /** - * Converts this condition to an expression reference if the condition has a result assignment. Otherwise throws - * an exception. - * - * @return the result as a reference expression. - */ + @Override + public Builder toConditionBuilder() { + return toBuilder(); + } + + @Override + public Condition toCondition() { + return this; + } + + @Override public Expression toExpression() { if (result == null) { throw new RuntimeException("Cannot generate expression from a condition without a result"); @@ -103,6 +109,12 @@ public Expression toExpression() { return Expression.getReference(result, javaLocation()); } + public Builder toBuilder() { + return builder() + .fn(function) + .result(result); + } + @Override public Type typeCheck(Scope scope) { Type conditionType = function.typeCheck(scope); diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/Rule.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/Rule.java index 26442a34842..f8b46ccd301 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/Rule.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/Rule.java @@ -24,6 +24,7 @@ import software.amazon.smithy.rulesengine.language.evaluation.Scope; import software.amazon.smithy.rulesengine.language.evaluation.TypeCheck; import software.amazon.smithy.rulesengine.language.evaluation.type.Type; +import software.amazon.smithy.rulesengine.language.syntax.ToCondition; import software.amazon.smithy.rulesengine.language.syntax.expressions.Expression; import software.amazon.smithy.rulesengine.language.syntax.expressions.literal.Literal; import software.amazon.smithy.utils.SmithyUnstableApi; @@ -42,14 +43,16 @@ public abstract class Rule implements TypeCheck, ToNode, FromSourceLocation { public static final String TYPE = "type"; private static final String CONDITIONS = "conditions"; - private final SourceLocation sourceLocation; - private final List conditions; + private final List conditions = new ArrayList<>(); private final String documentation; + private final SourceLocation sourceLocation; protected Rule(Builder builder) { - this.conditions = builder.conditions; - this.documentation = builder.documentation; - this.sourceLocation = builder.sourceLocation; + for (ToCondition condition : builder.conditions) { + conditions.add(condition.toCondition()); + } + documentation = builder.documentation; + sourceLocation = builder.sourceLocation; } /** @@ -201,7 +204,7 @@ public String toString() { * A builder used to create a {@link Rule} class. */ public static final class Builder { - private final List conditions = new ArrayList<>(); + private final List conditions = new ArrayList<>(); private final SourceLocation sourceLocation; private Function onBuild = Function.identity(); private String documentation; @@ -210,19 +213,19 @@ private Builder(FromSourceLocation sourceLocation) { this.sourceLocation = sourceLocation.getSourceLocation(); } - public Builder conditions(Condition... conditions) { - for (Condition condition : conditions) { - condition(condition); + public Builder conditions(ToCondition... conditions) { + for (ToCondition condition : conditions) { + condition(condition.toCondition()); } return this; } - public Builder conditions(List conditions) { + public Builder conditions(List conditions) { this.conditions.addAll(conditions); return this; } - public Builder condition(Condition condition) { + public Builder condition(ToCondition condition) { this.conditions.add(condition); return this; } @@ -258,9 +261,16 @@ public Builder description(String description) { } /** - * If `condition` IS met, return an error. Otherwise, proceed with the rules generated by the returned builder + * If `condition` IS met, return an error. Otherwise, proceed with the rules generated by + * the returned builder. + *

+ * This method returns a new builder that must be used! + * + * @param condition a coercible {@link Condition} + * @param error an error description if the condition is not matched + * @return new builder to attach subsequent rules to */ - public Builder errorOrElse(String error, Condition... condition) { + public Builder errorOrElse(String error, ToCondition... condition) { Builder next = new Builder(javaLocation()); next.onBuild = (Rule rule) -> this.treeRule(Rule.builder().conditions(condition).error(error), rule); return next; @@ -268,7 +278,7 @@ public Builder errorOrElse(String error, Condition... condition) { } /** - * If `condition` is not met, return an error. Otherwise, proceed with the rules generated by + * If `condition` IS NOT met, return an error. Otherwise, proceed with the rules generated by * the returned builder. *

* This method returns a new builder that must be used! @@ -277,7 +287,7 @@ public Builder errorOrElse(String error, Condition... condition) { * @param error an error description if the condition is not matched * @return new builder to attach subsequent rules to */ - public Builder validateOrElse(String error, Condition... condition) { + public Builder validateOrElse(String error, ToCondition... condition) { Builder next = new Builder(javaLocation()); next.onBuild = (Rule rule) -> this.treeRule( Rule.builder().conditions(condition).treeRule(rule), diff --git a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/syntax/functions/FunctionsTest.java b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/syntax/functions/FunctionsTest.java index 2c62382bea0..0f60d3d4da0 100644 --- a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/syntax/functions/FunctionsTest.java +++ b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/syntax/functions/FunctionsTest.java @@ -18,23 +18,32 @@ public class FunctionsTest { @Test - public void booleanEqualsOfExpression() { - BooleanEquals function = BooleanEquals.ofExpressions(Expression.of(true), Expression.of(true)); + public void booleanEqualsOfExpressions() { + BooleanEquals function = BooleanEquals.ofExpressions(Expression.of(true), true); assertThat(function, instanceOf(BooleanEquals.class)); + + BooleanEquals function2 = BooleanEquals.ofExpressions(Expression.of(true), Expression.of(true)); + assertThat(function2, instanceOf(BooleanEquals.class)); } @Test - public void getAttrOfExpression() { + public void getAttrOfExpressions() { GetAttr function = GetAttr.ofExpressions( - Expression.getReference(Identifier.of("a"), SourceLocation.none()), - Expression.of("b")); + Expression.getReference(Identifier.of("a"), SourceLocation.none()), "b"); assertThat(function, instanceOf(GetAttr.class)); + + GetAttr function2 = GetAttr.ofExpressions( + Expression.getReference(Identifier.of("a"), SourceLocation.none()), Expression.of("b")); + assertThat(function2, instanceOf(GetAttr.class)); } @Test public void isValidHostLabelOfExpression() { - IsValidHostLabel function = IsValidHostLabel.ofExpressions(Expression.of("foobar"), Expression.of(true)); + IsValidHostLabel function = IsValidHostLabel.ofExpressions(Expression.of("foobar"), true); assertThat(function, instanceOf(IsValidHostLabel.class)); + + IsValidHostLabel function2 = IsValidHostLabel.ofExpressions(Expression.of("foobar"), Expression.of(true)); + assertThat(function2, instanceOf(IsValidHostLabel.class)); } @Test @@ -53,18 +62,24 @@ public void parseUrlOfExpression() { @Test public void stringEqualsOfExpression() { - StringEquals function = StringEquals.ofExpressions(Expression.of("foo"), Expression.of("foo")); + StringEquals function = StringEquals.ofExpressions(Expression.of("foo"), "foo"); assertThat(function, instanceOf(StringEquals.class)); + + StringEquals function2 = StringEquals.ofExpressions(Expression.of("foo"), Expression.of("foo")); + assertThat(function2, instanceOf(StringEquals.class)); } @Test public void substringOfExpression() { - Substring function = Substring.ofExpressions( + Substring function = Substring.ofExpressions(Expression.of("foobar"), 1, 2, false); + assertThat(function, instanceOf(Substring.class)); + + Substring function2 = Substring.ofExpressions( Expression.of("foobar"), Expression.of(1), Expression.of(2), Expression.of(false)); - assertThat(function, instanceOf(Substring.class)); + assertThat(function2, instanceOf(Substring.class)); } @Test diff --git a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/syntax/functions/SyntaxElementTest.java b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/syntax/functions/SyntaxElementTest.java new file mode 100644 index 00000000000..fbfb955d871 --- /dev/null +++ b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/syntax/functions/SyntaxElementTest.java @@ -0,0 +1,89 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package software.amazon.smithy.rulesengine.language.syntax.functions; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.expressions.Expression; +import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.BooleanEquals; +import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.GetAttr; +import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.IsSet; +import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.IsValidHostLabel; +import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.Not; +import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.ParseUrl; +import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.StringEquals; +import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.Substring; + +public class SyntaxElementTest { + @Test + void booleanEquals() { + Expression bool = Expression.of(true); + BooleanEquals booleanEquals = bool.booleanEqual(false); + assertTrue(booleanEquals.getArguments().contains(bool)); + assertTrue(booleanEquals.getArguments().contains(Expression.of(false))); + } + + @Test + void stringEquals() { + Expression str = Expression.of("foo"); + StringEquals stringEquals = str.stringEqual("bar"); + assertTrue(stringEquals.getArguments().contains(str)); + assertTrue(stringEquals.getArguments().contains(Expression.of("bar"))); + } + + @Test + void getAttr() { + Expression str = Expression.of("http://example.com"); + ParseUrl parseUrl = str.parseUrl(); + GetAttr getAttr1 = parseUrl.getAttr("scheme"); + assertTrue(getAttr1.getArguments().contains(Expression.of("scheme"))); + + GetAttr getAttr2 = parseUrl.getAttr(Identifier.of("scheme")); + assertTrue(getAttr2.getArguments().contains(Expression.of("scheme"))); + } + + @Test + void isSet() { + Expression str = Expression.of("foo"); + IsSet isSet = str.isSet(); + assertTrue(isSet.getArguments().contains(str)); + } + + @Test + void isValidHostLabel() { + Expression str = Expression.of("foo"); + IsValidHostLabel isValidHostLabel = str.isValidHostLabel(true); + assertTrue(isValidHostLabel.getArguments().contains(str)); + assertTrue(isValidHostLabel.getArguments().contains(Expression.of(true))); + } + + @Test + void not() { + Expression bool = Expression.of(true); + Not not = bool.not(); + assertTrue(not.getArguments().contains(bool)); + } + + @Test + void parseUrl() { + Expression str = Expression.of("http://example.com"); + ParseUrl parseUrl = str.parseUrl(); + assertTrue(parseUrl.getArguments().contains(str)); + } + + @Test + void substring() { + Expression str = Expression.of("foo"); + Substring substring = str.substring(1, 2, false); + assertTrue(substring.getArguments().contains(str)); + assertTrue(substring.getArguments().contains(Expression.of(1))); + assertTrue(substring.getArguments().contains(Expression.of(2))); + assertTrue(substring.getArguments().contains(Expression.of(false))); + + } +} diff --git a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/syntax/rule/RuleTest.java b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/syntax/rule/RuleTest.java index ec82670f160..9c4c92d5024 100644 --- a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/syntax/rule/RuleTest.java +++ b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/syntax/rule/RuleTest.java @@ -23,9 +23,9 @@ public void validateAndErrorsTest() { Parameter p1 = Parameter.builder().name("param1").type(ParameterType.STRING).required(true).build(); Parameter p2 = Parameter.builder().name("param2").type(ParameterType.STRING).required(true).build(); Parameter p3 = Parameter.builder().name("param3").type(ParameterType.STRING).required(true).build(); - StringEquals equalsA = StringEquals.ofExpressions(p1.toExpression(), Expression.of("a")); - StringEquals equalsB = StringEquals.ofExpressions(p2.toExpression(), Expression.of("b")); - StringEquals equalsC = StringEquals.ofExpressions(p3.toExpression(), Expression.of("c")); + StringEquals equalsA = StringEquals.ofExpressions(p1.toExpression(), "a"); + StringEquals equalsB = StringEquals.ofExpressions(p2.toExpression(), "b"); + StringEquals equalsC = StringEquals.ofExpressions(p3.toExpression(), "c"); Rule rule = Rule.builder() .validateOrElse("param1 value is not a", condition(equalsA)) .errorOrElse("param2 is b", condition(equalsB)) diff --git a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/value/TemplateTest.java b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/value/TemplateTest.java index 1a86938fb65..a94852a6512 100644 --- a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/value/TemplateTest.java +++ b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/value/TemplateTest.java @@ -38,11 +38,9 @@ private void checkTemplateParts(String templateInput, String... parts) { public void validateShortformParsing() { assertEquals(Expression.parseShortform("a", SourceLocation.none()), Expression.getReference(Identifier.of("a"), SourceLocation.none())); assertEquals(Expression.parseShortform("a#b", SourceLocation.none()), GetAttr.ofExpressions( - Expression.getReference(Identifier.of("a"), SourceLocation.none()), - Expression.of("b"))); + Expression.getReference(Identifier.of("a"), SourceLocation.none()), "b")); assertEquals(Expression.parseShortform("a#b.c", SourceLocation.none()), GetAttr.ofExpressions( - Expression.getReference(Identifier.of("a"), SourceLocation.none()), - Expression.of("b.c"))); + Expression.getReference(Identifier.of("a"), SourceLocation.none()), "b.c")); } @Test