Skip to content

Commit 3d96135

Browse files
committed
Add JMESPath to_number function
1 parent 1833c59 commit 3d96135

File tree

2 files changed

+41
-5
lines changed

2 files changed

+41
-5
lines changed

jmespath/src/main/java/software/amazon/smithy/java/jmespath/JMESPathFunction.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,23 @@ protected Document applyImpl(List<Document> arguments, ExpressionTypeExpression
415415
},
416416
TO_NUMBER("to_number", 1) {
417417
@Override
418-
protected Document applyImpl(List<Document> argument, ExpressionTypeExpression fnRef) {
419-
throw new UnsupportedOperationException("to_number function is not supported");
418+
protected Document applyImpl(List<Document> arguments, ExpressionTypeExpression fnRef) {
419+
var argument = arguments.get(0);
420+
if (argument == null) {
421+
return null;
422+
}
423+
return switch (argument.type()) {
424+
case STRING -> {
425+
try {
426+
yield Document.ofNumber(new BigDecimal(argument.asString()));
427+
} catch (NumberFormatException e) {
428+
yield null;
429+
}
430+
}
431+
case SHORT, BYTE, INTEGER, INT_ENUM, LONG, FLOAT, DOUBLE, BIG_DECIMAL, BIG_INTEGER ->
432+
Document.ofNumber(argument.asNumber());
433+
default -> null;
434+
};
420435
}
421436
},
422437
TYPE("type", 1) {

jmespath/src/test/java/software/amazon/smithy/java/jmespath/ComplianceTestRunner.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.io.FileNotFoundException;
1111
import java.io.IOException;
1212
import java.io.UncheckedIOException;
13+
import java.math.BigDecimal;
1314
import java.net.URISyntaxException;
1415
import java.net.URL;
1516
import java.nio.file.Path;
@@ -40,7 +41,6 @@ class ComplianceTestRunner {
4041
private static final NodeToDocumentConverter CONVERTER = new NodeToDocumentConverter();
4142
// TODO: Remove these suppressions as remaining functions are supported
4243
private static final List<String> UNSUPPORTED_FUNCTIONS = List.of(
43-
"to_number",
4444
"to_string",
4545
"to_array",
4646
"merge",
@@ -145,8 +145,7 @@ public void run() {
145145
private static boolean isEqual(Document expected, Document actual) {
146146
if (expected == null || actual == null) {
147147
return expected == null && actual == null;
148-
}
149-
if (expected.type().equals(ShapeType.MAP) && actual.type().equals(ShapeType.MAP)) {
148+
} else if (expected.type().equals(ShapeType.MAP) && actual.type().equals(ShapeType.MAP)) {
150149
for (var member : expected.getMemberNames()) {
151150
var expectedMember = expected.getMember(member);
152151
var actualMember = actual.getMember(member);
@@ -155,10 +154,32 @@ private static boolean isEqual(Document expected, Document actual) {
155154
}
156155
}
157156
return true;
157+
} else if (expected.type().equals(ShapeType.LIST) && actual.type().equals(ShapeType.LIST)) {
158+
if (expected.size() != actual.size()) {
159+
return false;
160+
} else {
161+
for (int i = 0; i < expected.size(); i++) {
162+
if (!isEqual(expected.asList().get(i), actual.asList().get(i))) {
163+
return false;
164+
}
165+
}
166+
return true;
167+
}
168+
} else if (isNumeric(expected) && isNumeric(actual)) {
169+
// Normalize all numbers to BigDecimal to make comparisons work.
170+
return new BigDecimal(expected.asNumber().toString())
171+
.compareTo(new BigDecimal(actual.asNumber().toString())) == 0;
158172
}
159173
return Objects.equals(expected, actual);
160174
}
161175

176+
private static boolean isNumeric(Document doc) {
177+
var type = doc.type();
178+
return type == ShapeType.BYTE || type == ShapeType.SHORT || type == ShapeType.INTEGER
179+
|| type == ShapeType.LONG || type == ShapeType.BIG_INTEGER || type == ShapeType.BIG_DECIMAL
180+
|| type == ShapeType.FLOAT || type == ShapeType.DOUBLE || type == ShapeType.INT_ENUM;
181+
}
182+
162183
private static final class NodeToDocumentConverter implements NodeVisitor<Document> {
163184
private Document convert(Node node) {
164185
return node.accept(this);

0 commit comments

Comments
 (0)