diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/RuleEvaluator.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/RuleEvaluator.java index 4ea596e83d5..40dab3c27a7 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/RuleEvaluator.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/RuleEvaluator.java @@ -120,7 +120,6 @@ public Value visitLibraryFunction(FunctionDefinition definition, List { for (Condition condition : rule.getConditions()) { Value value = evaluateCondition(condition); @@ -143,28 +142,37 @@ public Value visitTreeRule(List rules) { @Override public Value visitErrorRule(Expression error) { - return error.accept(self); + return RuleEvaluator.this.visitErrorRule(error); } @Override public Value visitEndpointRule(Endpoint endpoint) { - Value.Endpoint.Builder builder = Value.Endpoint.builder() - .sourceLocation(endpoint) - .url(endpoint.getUrl() - .accept(RuleEvaluator.this) - .expectString()); - endpoint.getProperties() - .forEach((key, value) -> builder.addProperty(key.toString(), - value.accept(RuleEvaluator.this))); - endpoint.getHeaders() - .forEach((name, expressions) -> expressions.forEach(expr -> builder.addHeader(name, - expr.accept(RuleEvaluator.this).expectString()))); - return builder.build(); + return RuleEvaluator.this.visitEndpointRule(endpoint); } }); }); } + public Value visitErrorRule(Expression error) { + return error.accept(this); + } + + public Value visitEndpointRule(Endpoint endpoint) { + Value.Endpoint.Builder builder = Value.Endpoint.builder() + .sourceLocation(endpoint) + .url(endpoint.getUrl() + .accept(RuleEvaluator.this) + .expectString()); + endpoint.getProperties() + .forEach((key, value) -> builder.addProperty(key.toString(), + value.accept(RuleEvaluator.this))); + endpoint.getHeaders() + .forEach((name, expressions) -> expressions.forEach(expr -> builder.addHeader(name, + expr.accept(RuleEvaluator.this).expectString()))); + return builder.build(); + + } + public Value evaluateCondition(Condition condition) { Value value = condition.getFn().accept(this); if (!value.isNone()) { diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/BooleanEquals.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/BooleanEquals.java index bf5b8c944cf..7cc3d15cb24 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/BooleanEquals.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/BooleanEquals.java @@ -48,8 +48,8 @@ public BooleanEquals(FunctionNode functionNode) { * @param right the right hand-side expression. * @return the function defining the BooleanEquals of the left and right expressions. */ - public static Function ofExpressions(Expression left, Expression right) { - return LibraryFunction.ofExpressions(DEFINITION, left, right); + public static BooleanEquals ofExpressions(Expression left, Expression right) { + return new BooleanEquals(FunctionNode.ofExpressions(DEFINITION.getId(), left, right)); } @Override diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/StringEquals.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/StringEquals.java index 4460f5cbeaf..95bf6f7de13 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/StringEquals.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/StringEquals.java @@ -48,8 +48,8 @@ public StringEquals(FunctionNode functionNode) { * @param right the right expression. * @return a function instance representing the StringEquals comparison. */ - public static Function ofExpressions(Expression left, Expression right) { - return LibraryFunction.ofExpressions(DEFINITION, left, right); + public static StringEquals ofExpressions(Expression left, Expression right) { + return new StringEquals(FunctionNode.ofExpressions(DEFINITION.getId(), left, right)); } @Override diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/traits/ContextIndex.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/traits/ContextIndex.java index 30c2e544868..41a0842c8af 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/traits/ContextIndex.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/traits/ContextIndex.java @@ -16,6 +16,7 @@ package software.amazon.smithy.rulesengine.traits; import java.lang.ref.WeakReference; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -25,7 +26,6 @@ import software.amazon.smithy.model.shapes.MemberShape; import software.amazon.smithy.model.shapes.OperationShape; import software.amazon.smithy.model.shapes.Shape; -import software.amazon.smithy.utils.MapUtils; import software.amazon.smithy.utils.Pair; import software.amazon.smithy.utils.SmithyUnstableApi; @@ -77,11 +77,14 @@ public Map getContextParams(Shape operation) { .orElseThrow(() -> new IllegalArgumentException(operation.toShapeId() + " is not an operation shape")); - return getModel().expectShape(operationShape.getInputShape()) + LinkedHashMap out = new LinkedHashMap<>(); + + getModel().expectShape(operationShape.getInputShape()) .members().stream() .map(memberShape -> Pair.of(memberShape, memberShape.getTrait(ContextParamTrait.class))) .filter(pair -> pair.right.isPresent()) - .collect(MapUtils.toUnmodifiableMap(pair -> pair.left, pair -> pair.right.get())); + .forEach(pair -> out.put(pair.left, pair.right.get())); + return out; } private Model getModel() { diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/traits/ExpectedEndpoint.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/traits/ExpectedEndpoint.java index 2d2283ca55e..6691aa3ddfd 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/traits/ExpectedEndpoint.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/traits/ExpectedEndpoint.java @@ -104,7 +104,11 @@ public String toString() { } if (!properties.isEmpty()) { sb.append("properties:\n"); - properties.forEach((k, v) -> sb.append(StringUtils.indent(String.format("%s: %s", k, v), 2))); + properties.forEach((k, v) -> sb + .append( + StringUtils.indent( + String.format("%s: %s", k, Node.prettyPrintJson(v)), 2) + )); } return sb.toString(); } diff --git a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/fn/FunctionOfExprsTest.java b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/fn/FunctionOfExprsTest.java new file mode 100644 index 00000000000..b9ef3951dba --- /dev/null +++ b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/fn/FunctionOfExprsTest.java @@ -0,0 +1,69 @@ +package software.amazon.smithy.rulesengine.language.fn; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; +import org.junit.jupiter.api.Test; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expression; +import software.amazon.smithy.rulesengine.language.syntax.fn.FunctionDefinition; +import software.amazon.smithy.rulesengine.language.visit.ExpressionVisitor; + +public class FunctionOfExprsTest { + + @Test + void boolEquals() { + Expression boolEquals = Expression.of(true).equal(true); + assertEquals(boolEquals.accept(new ExpectLibFunction()), false); + assertEquals(boolEquals.accept(new ExpectBuiltInFunction()), "bool"); + } + + + @Test + void stringEquals() { + Expression stringEquals = Expression.of("asdf").equal("asdf"); + assertEquals(stringEquals.accept(new ExpectLibFunction()), false); + assertEquals(stringEquals.accept(new ExpectBuiltInFunction()), "string"); + } + + @Test + void not() { + Expression not = Expression.of("asdf").equal("asdf").not(); + assertEquals(not.accept(new ExpectLibFunction()), false); + assertEquals(not.accept(new ExpectBuiltInFunction()), "not"); + } + + static class ExpectLibFunction extends ExpressionVisitor.Default { + @Override + public Boolean visitLibraryFunction(FunctionDefinition fn, List args) { + return true; + } + + @Override + public Boolean getDefault() { + return false; + } + } + + static class ExpectBuiltInFunction extends ExpressionVisitor.Default { + @Override + public String getDefault() { + return "other"; + } + + @Override + public String visitBoolEquals(Expression left, Expression right) { + return "bool"; + } + + + @Override + public String visitStringEquals(Expression left, Expression right) { + return "string"; + } + + @Override + public String visitNot(Expression not) { + return "not"; + } + } +}