From e4f1916f27c912fdb63bb49c1480b3bf8d92fdd8 Mon Sep 17 00:00:00 2001 From: Steve Ayers Date: Tue, 29 Apr 2025 17:47:07 -0400 Subject: [PATCH 1/8] Duration --- src/main/java/build/buf/protovalidate/Format.java | 11 ++--------- src/test/java/build/buf/protovalidate/FormatTest.java | 8 ++++++++ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main/java/build/buf/protovalidate/Format.java b/src/main/java/build/buf/protovalidate/Format.java index 80faeb0c..49ce48ee 100644 --- a/src/main/java/build/buf/protovalidate/Format.java +++ b/src/main/java/build/buf/protovalidate/Format.java @@ -176,7 +176,7 @@ private static void formatStringSafe(StringBuilder builder, Val val, boolean lis } else if (type == TypeEnum.Bytes) { formatBytes(builder, val); } else if (type == TypeEnum.Duration) { - formatDuration(builder, val, listType); + formatDuration(builder, val); } else if (type == TypeEnum.Timestamp) { formatTimestamp(builder, val); } else if (type == TypeEnum.List) { @@ -225,12 +225,8 @@ private static void formatTimestamp(StringBuilder builder, Val val) { * * @param builder the StringBuilder to append the formatted duration value to. * @param val the value to format. - * @param listType indicates if the value type is a list. */ - private static void formatDuration(StringBuilder builder, Val val, boolean listType) { - if (listType) { - builder.append("duration(\""); - } + private static void formatDuration(StringBuilder builder, Val val) { Duration duration = val.convertToNative(Duration.class); double totalSeconds = duration.getSeconds() + (duration.getNanos() / 1_000_000_000.0); @@ -238,9 +234,6 @@ private static void formatDuration(StringBuilder builder, Val val, boolean listT DecimalFormat format = new DecimalFormat("0.#########"); builder.append(format.format(totalSeconds)); builder.append("s"); - if (listType) { - builder.append("\")"); - } } /** diff --git a/src/test/java/build/buf/protovalidate/FormatTest.java b/src/test/java/build/buf/protovalidate/FormatTest.java index a5656505..65212ef7 100644 --- a/src/test/java/build/buf/protovalidate/FormatTest.java +++ b/src/test/java/build/buf/protovalidate/FormatTest.java @@ -29,4 +29,12 @@ void largeDecimalValuesAreProperlyFormatted() { String formatted = Format.format("%s", val); assertThat(formatted).isEqualTo("999999999999"); } + + @Test + void testDurationSecondsOnly() { + UintT largeDecimal = UintT.uintOf(999999999999L); + ListT val = (ListT) ListT.newValArrayList(null, new Val[] {largeDecimal}); + String formatted = Format.format("%s", val); + assertThat(formatted).isEqualTo("999999999999"); + } } From 3cab97f1d5f3cd9ae6459c803d92a754f65c8c07 Mon Sep 17 00:00:00 2001 From: Steve Ayers Date: Tue, 29 Apr 2025 18:03:43 -0400 Subject: [PATCH 2/8] Add tests for duration format --- .../build/buf/protovalidate/FormatTest.java | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/test/java/build/buf/protovalidate/FormatTest.java b/src/test/java/build/buf/protovalidate/FormatTest.java index 65212ef7..470e3153 100644 --- a/src/test/java/build/buf/protovalidate/FormatTest.java +++ b/src/test/java/build/buf/protovalidate/FormatTest.java @@ -16,9 +16,11 @@ import static org.assertj.core.api.Assertions.assertThat; +import com.google.protobuf.Duration; import org.junit.jupiter.api.Test; import org.projectnessie.cel.common.types.ListT; import org.projectnessie.cel.common.types.UintT; +import org.projectnessie.cel.common.types.pb.DefaultTypeAdapter; import org.projectnessie.cel.common.types.ref.Val; class FormatTest { @@ -30,11 +32,42 @@ void largeDecimalValuesAreProperlyFormatted() { assertThat(formatted).isEqualTo("999999999999"); } + @Test + void testDuration() { + Duration duration = Duration.newBuilder().setSeconds(123).setNanos(45678).build(); + + ListT val = + (ListT) ListT.newGenericArrayList(DefaultTypeAdapter.Instance, new Duration[] {duration}); + String formatted = Format.format("%s", val); + assertThat(formatted).isEqualTo("123.000045678s"); + } + + @Test + void testEmptyDuration() { + Duration duration = Duration.newBuilder().build(); + ListT val = + (ListT) ListT.newGenericArrayList(DefaultTypeAdapter.Instance, new Duration[] {duration}); + String formatted = Format.format("%s", val); + assertThat(formatted).isEqualTo("0s"); + } + @Test void testDurationSecondsOnly() { - UintT largeDecimal = UintT.uintOf(999999999999L); - ListT val = (ListT) ListT.newValArrayList(null, new Val[] {largeDecimal}); + Duration duration = Duration.newBuilder().setSeconds(123).build(); + + ListT val = + (ListT) ListT.newGenericArrayList(DefaultTypeAdapter.Instance, new Duration[] {duration}); String formatted = Format.format("%s", val); - assertThat(formatted).isEqualTo("999999999999"); + assertThat(formatted).isEqualTo("123s"); + } + + @Test + void testDurationNanosOnly() { + Duration duration = Duration.newBuilder().setNanos(42).build(); + + ListT val = + (ListT) ListT.newGenericArrayList(DefaultTypeAdapter.Instance, new Duration[] {duration}); + String formatted = Format.format("%s", val); + assertThat(formatted).isEqualTo("0.000000042s"); } } From ea5ff7217ac5e21471a56446f1e2b4336c12ced8 Mon Sep 17 00:00:00 2001 From: Steve Ayers Date: Tue, 29 Apr 2025 18:06:48 -0400 Subject: [PATCH 3/8] Format --- conformance/expected-failures.yaml | 6 ------ src/main/java/build/buf/protovalidate/Format.java | 8 ++++---- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/conformance/expected-failures.yaml b/conformance/expected-failures.yaml index 9055e245..8cae39fa 100644 --- a/conformance/expected-failures.yaml +++ b/conformance/expected-failures.yaml @@ -24,9 +24,3 @@ kitchen_sink: - field/transitive/invalid - many/all-non-message-fields/invalid - field/invalid -standard_rules/repeated: - - items/in/invalid - - items/not_in/invalid -standard_rules/well_known_types/duration: - - in/invalid - - not in/invalid diff --git a/src/main/java/build/buf/protovalidate/Format.java b/src/main/java/build/buf/protovalidate/Format.java index 49ce48ee..f80d4f4a 100644 --- a/src/main/java/build/buf/protovalidate/Format.java +++ b/src/main/java/build/buf/protovalidate/Format.java @@ -147,7 +147,7 @@ private static void formatString(StringBuilder builder, Val val) { DecimalFormat format = new DecimalFormat(); builder.append(format.format(val.value())); } else { - formatStringSafe(builder, val, false); + formatStringSafe(builder, val); } } @@ -158,7 +158,7 @@ private static void formatString(StringBuilder builder, Val val) { * @param val the value to format. * @param listType indicates if the value type is a list. */ - private static void formatStringSafe(StringBuilder builder, Val val, boolean listType) { + private static void formatStringSafe(StringBuilder builder, Val val) { TypeEnum type = val.type().typeEnum(); if (type == TypeEnum.Bool) { builder.append(val.booleanValue()); @@ -172,7 +172,7 @@ private static void formatStringSafe(StringBuilder builder, Val val, boolean lis format.setMinimumFractionDigits(6); builder.append(format.format(val.value())); } else if (type == TypeEnum.String) { - builder.append("\"").append(val.value().toString()).append("\""); + builder.append(val.value()); } else if (type == TypeEnum.Bytes) { formatBytes(builder, val); } else if (type == TypeEnum.Duration) { @@ -200,7 +200,7 @@ private static void formatList(StringBuilder builder, Val val) { List list = val.convertToNative(List.class); for (int i = 0; i < list.size(); i++) { Object obj = list.get(i); - formatStringSafe(builder, DefaultTypeAdapter.nativeToValue(Db.newDb(), null, obj), true); + formatStringSafe(builder, DefaultTypeAdapter.nativeToValue(Db.newDb(), null, obj)); if (i != list.size() - 1) { builder.append(", "); } From 4dbc4f38370727d33f562a8ea8982696c6e755ae Mon Sep 17 00:00:00 2001 From: Steve Ayers Date: Wed, 30 Apr 2025 11:03:58 -0400 Subject: [PATCH 4/8] Tests --- build.gradle.kts | 8 ++++ .../java/build/buf/protovalidate/Format.java | 34 ++------------ .../build/buf/protovalidate/FormatTest.java | 47 ++++++++++++++++++- 3 files changed, 59 insertions(+), 30 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index c50440c4..a7d15608 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -207,6 +207,14 @@ allprojects { } tasks.withType().configureEach { useJUnitPlatform() + this.testLogging { + this.showStandardStreams = true + events("failed") + exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL + showExceptions = true + showCauses = true + showStackTraces = true + } } } diff --git a/src/main/java/build/buf/protovalidate/Format.java b/src/main/java/build/buf/protovalidate/Format.java index f80d4f4a..be3e21fa 100644 --- a/src/main/java/build/buf/protovalidate/Format.java +++ b/src/main/java/build/buf/protovalidate/Format.java @@ -144,7 +144,7 @@ private static void formatString(StringBuilder builder, Val val) { } else if (val.type().typeEnum() == TypeEnum.Bytes) { builder.append(new String((byte[]) val.value(), StandardCharsets.UTF_8)); } else if (val.type().typeEnum() == TypeEnum.Double) { - DecimalFormat format = new DecimalFormat(); + DecimalFormat format = new DecimalFormat("0.##"); builder.append(format.format(val.value())); } else { formatStringSafe(builder, val); @@ -156,7 +156,6 @@ private static void formatString(StringBuilder builder, Val val) { * * @param builder the StringBuilder to append the formatted string to. * @param val the value to format. - * @param listType indicates if the value type is a list. */ private static void formatStringSafe(StringBuilder builder, Val val) { TypeEnum type = val.type().typeEnum(); @@ -164,17 +163,6 @@ private static void formatStringSafe(StringBuilder builder, Val val) { builder.append(val.booleanValue()); } else if (type == TypeEnum.Int || type == TypeEnum.Uint) { formatDecimal(builder, val); - } else if (type == TypeEnum.Double) { - // When a double is nested in another type (e.g. a list) it will have a minimum of 6 decimal - // digits. This is to maintain consistency with the Go CEL runtime. - DecimalFormat format = new DecimalFormat(); - format.setMaximumFractionDigits(Integer.MAX_VALUE); - format.setMinimumFractionDigits(6); - builder.append(format.format(val.value())); - } else if (type == TypeEnum.String) { - builder.append(val.value()); - } else if (type == TypeEnum.Bytes) { - formatBytes(builder, val); } else if (type == TypeEnum.Duration) { formatDuration(builder, val); } else if (type == TypeEnum.Timestamp) { @@ -236,19 +224,6 @@ private static void formatDuration(StringBuilder builder, Val val) { builder.append("s"); } - /** - * Formats a byte array value. - * - * @param builder the StringBuilder to append the formatted byte array value to. - * @param val the value to format. - */ - private static void formatBytes(StringBuilder builder, Val val) { - builder - .append("\"") - .append(new String((byte[]) val.value(), StandardCharsets.UTF_8)) - .append("\""); - } - /** * Formats a hexadecimal value. * @@ -276,9 +251,10 @@ private static void formatHex(StringBuilder builder, Val val, char[] digits) { * Formats a decimal value. * * @param builder the StringBuilder to append the formatted decimal value to. - * @param arg the value to format. + * @param val the value to format. */ - private static void formatDecimal(StringBuilder builder, Val arg) { - builder.append(arg.value()); + private static void formatDecimal(StringBuilder builder, Val val) { + DecimalFormat format = new DecimalFormat("0.#########"); + builder.append(format.format(val.value())); } } diff --git a/src/test/java/build/buf/protovalidate/FormatTest.java b/src/test/java/build/buf/protovalidate/FormatTest.java index 470e3153..ef0b1fb1 100644 --- a/src/test/java/build/buf/protovalidate/FormatTest.java +++ b/src/test/java/build/buf/protovalidate/FormatTest.java @@ -15,17 +15,62 @@ package build.buf.protovalidate; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.google.protobuf.Duration; import org.junit.jupiter.api.Test; +import org.projectnessie.cel.common.types.DoubleT; +import org.projectnessie.cel.common.types.Err.ErrException; import org.projectnessie.cel.common.types.ListT; +import org.projectnessie.cel.common.types.StringT; import org.projectnessie.cel.common.types.UintT; import org.projectnessie.cel.common.types.pb.DefaultTypeAdapter; import org.projectnessie.cel.common.types.ref.Val; class FormatTest { @Test - void largeDecimalValuesAreProperlyFormatted() { + void testNotEnoughArgumentsThrows() { + StringT one = StringT.stringOf("one"); + ListT val = (ListT) ListT.newValArrayList(null, new Val[] {one}); + + assertThatThrownBy( + () -> { + Format.format("first value: %s and %s", val); + }) + .isInstanceOf(ErrException.class) + .hasMessageContaining("format: not enough arguments"); + } + + @Test + void testDouble() { + ListT val = + (ListT) + ListT.newValArrayList( + null, + new Val[] { + DoubleT.doubleOf(-1.20000000000), + DoubleT.doubleOf(-1.2), + DoubleT.doubleOf(-1.230), + DoubleT.doubleOf(-1.002), + DoubleT.doubleOf(-0.1), + DoubleT.doubleOf(-.1), + DoubleT.doubleOf(-1), + DoubleT.doubleOf(-0.0), + DoubleT.doubleOf(0), + DoubleT.doubleOf(0.0), + DoubleT.doubleOf(1), + DoubleT.doubleOf(0.1), + DoubleT.doubleOf(.1), + DoubleT.doubleOf(1.002), + DoubleT.doubleOf(1.230), + DoubleT.doubleOf(1.20000000000) + }); + String formatted = Format.format("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", val); + assertThat(formatted).isEqualTo("-1.2, -1.2, -1.23, -1.002, -0.1, -0.1, -1, -0, 0, 0, 1, 0.1, 0.1, 1.002, 1.23, 1.2"); + } + + @Test + void testLargeDecimalValuesAreProperlyFormatted() { UintT largeDecimal = UintT.uintOf(999999999999L); ListT val = (ListT) ListT.newValArrayList(null, new Val[] {largeDecimal}); String formatted = Format.format("%s", val); From 26665e1b5b2cd16eda3d00903d05701909a16940 Mon Sep 17 00:00:00 2001 From: Steve Ayers Date: Wed, 30 Apr 2025 11:16:07 -0400 Subject: [PATCH 5/8] Adds some additional formatting tests --- conformance/expected-failures.yaml | 5 --- .../java/build/buf/protovalidate/Format.java | 38 ++++++------------- 2 files changed, 11 insertions(+), 32 deletions(-) diff --git a/conformance/expected-failures.yaml b/conformance/expected-failures.yaml index c771d190..17daf1bf 100644 --- a/conformance/expected-failures.yaml +++ b/conformance/expected-failures.yaml @@ -15,8 +15,3 @@ custom_rules: - field_expression/map/int64/invalid - field_expression/map/uint64/valid - field_expression/map/uint64/invalid -kitchen_sink: - - field/embedded/invalid - - field/transitive/invalid - - many/all-non-message-fields/invalid - - field/invalid diff --git a/src/main/java/build/buf/protovalidate/Format.java b/src/main/java/build/buf/protovalidate/Format.java index be3e21fa..8dd72654 100644 --- a/src/main/java/build/buf/protovalidate/Format.java +++ b/src/main/java/build/buf/protovalidate/Format.java @@ -34,6 +34,7 @@ final class Format { private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); private static final char[] LOWER_HEX_ARRAY = "0123456789abcdef".toCharArray(); +private static final DecimalFormat decimalFormat = new DecimalFormat("0.#########"); /** * Format the string with a {@link ListT}. @@ -139,29 +140,14 @@ private static String bytesToHex(byte[] bytes, char[] digits) { * @param val the value to format. */ private static void formatString(StringBuilder builder, Val val) { - if (val.type().typeEnum() == TypeEnum.String) { - builder.append(val.value()); - } else if (val.type().typeEnum() == TypeEnum.Bytes) { - builder.append(new String((byte[]) val.value(), StandardCharsets.UTF_8)); - } else if (val.type().typeEnum() == TypeEnum.Double) { - DecimalFormat format = new DecimalFormat("0.##"); - builder.append(format.format(val.value())); - } else { - formatStringSafe(builder, val); - } - } - - /** - * Formats a string value safely for other value types. - * - * @param builder the StringBuilder to append the formatted string to. - * @param val the value to format. - */ - private static void formatStringSafe(StringBuilder builder, Val val) { TypeEnum type = val.type().typeEnum(); if (type == TypeEnum.Bool) { builder.append(val.booleanValue()); - } else if (type == TypeEnum.Int || type == TypeEnum.Uint) { + } else if (type == TypeEnum.String) { + builder.append(val.value()); + } else if (type == TypeEnum.Bytes) { + builder.append(new String((byte[]) val.value(), StandardCharsets.UTF_8)); + } else if (type == TypeEnum.Int || type == TypeEnum.Uint || type == TypeEnum.Double) { formatDecimal(builder, val); } else if (type == TypeEnum.Duration) { formatDuration(builder, val); @@ -170,9 +156,9 @@ private static void formatStringSafe(StringBuilder builder, Val val) { } else if (type == TypeEnum.List) { formatList(builder, val); } else if (type == TypeEnum.Map) { - throw new ErrException("unimplemented stringSafe map type"); + throw new ErrException("unimplemented string map type"); } else if (type == TypeEnum.Null) { - throw new ErrException("unimplemented stringSafe null type"); + throw new ErrException("unimplemented string null type"); } } @@ -188,7 +174,7 @@ private static void formatList(StringBuilder builder, Val val) { List list = val.convertToNative(List.class); for (int i = 0; i < list.size(); i++) { Object obj = list.get(i); - formatStringSafe(builder, DefaultTypeAdapter.nativeToValue(Db.newDb(), null, obj)); + formatString(builder, DefaultTypeAdapter.nativeToValue(Db.newDb(), null, obj)); if (i != list.size() - 1) { builder.append(", "); } @@ -219,8 +205,7 @@ private static void formatDuration(StringBuilder builder, Val val) { double totalSeconds = duration.getSeconds() + (duration.getNanos() / 1_000_000_000.0); - DecimalFormat format = new DecimalFormat("0.#########"); - builder.append(format.format(totalSeconds)); + builder.append(decimalFormat.format(totalSeconds)); builder.append("s"); } @@ -254,7 +239,6 @@ private static void formatHex(StringBuilder builder, Val val, char[] digits) { * @param val the value to format. */ private static void formatDecimal(StringBuilder builder, Val val) { - DecimalFormat format = new DecimalFormat("0.#########"); - builder.append(format.format(val.value())); + builder.append(decimalFormat.format(val.value())); } } From aefec2ea6b8d19c19a12a847737665889003a5f0 Mon Sep 17 00:00:00 2001 From: Steve Ayers Date: Wed, 30 Apr 2025 11:18:58 -0400 Subject: [PATCH 6/8] Adds some additional formatting tests --- build.gradle.kts | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index a7d15608..8f17533e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -208,7 +208,6 @@ allprojects { tasks.withType().configureEach { useJUnitPlatform() this.testLogging { - this.showStandardStreams = true events("failed") exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL showExceptions = true From 7b75aaba92a31c77275d6d039adcc930befbe86e Mon Sep 17 00:00:00 2001 From: Steve Ayers Date: Wed, 30 Apr 2025 11:22:13 -0400 Subject: [PATCH 7/8] Format --- src/main/java/build/buf/protovalidate/Format.java | 6 +++--- src/test/java/build/buf/protovalidate/FormatTest.java | 7 +++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/build/buf/protovalidate/Format.java b/src/main/java/build/buf/protovalidate/Format.java index 8dd72654..81c3c176 100644 --- a/src/main/java/build/buf/protovalidate/Format.java +++ b/src/main/java/build/buf/protovalidate/Format.java @@ -34,7 +34,7 @@ final class Format { private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); private static final char[] LOWER_HEX_ARRAY = "0123456789abcdef".toCharArray(); -private static final DecimalFormat decimalFormat = new DecimalFormat("0.#########"); + private static final DecimalFormat decimalFormat = new DecimalFormat("0.#########"); /** * Format the string with a {@link ListT}. @@ -146,7 +146,7 @@ private static void formatString(StringBuilder builder, Val val) { } else if (type == TypeEnum.String) { builder.append(val.value()); } else if (type == TypeEnum.Bytes) { - builder.append(new String((byte[]) val.value(), StandardCharsets.UTF_8)); + builder.append(new String((byte[]) val.value(), StandardCharsets.UTF_8)); } else if (type == TypeEnum.Int || type == TypeEnum.Uint || type == TypeEnum.Double) { formatDecimal(builder, val); } else if (type == TypeEnum.Duration) { @@ -239,6 +239,6 @@ private static void formatHex(StringBuilder builder, Val val, char[] digits) { * @param val the value to format. */ private static void formatDecimal(StringBuilder builder, Val val) { - builder.append(decimalFormat.format(val.value())); + builder.append(decimalFormat.format(val.value())); } } diff --git a/src/test/java/build/buf/protovalidate/FormatTest.java b/src/test/java/build/buf/protovalidate/FormatTest.java index ef0b1fb1..962460a7 100644 --- a/src/test/java/build/buf/protovalidate/FormatTest.java +++ b/src/test/java/build/buf/protovalidate/FormatTest.java @@ -65,8 +65,11 @@ void testDouble() { DoubleT.doubleOf(1.230), DoubleT.doubleOf(1.20000000000) }); - String formatted = Format.format("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", val); - assertThat(formatted).isEqualTo("-1.2, -1.2, -1.23, -1.002, -0.1, -0.1, -1, -0, 0, 0, 1, 0.1, 0.1, 1.002, 1.23, 1.2"); + String formatted = + Format.format("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", val); + assertThat(formatted) + .isEqualTo( + "-1.2, -1.2, -1.23, -1.002, -0.1, -0.1, -1, -0, 0, 0, 1, 0.1, 0.1, 1.002, 1.23, 1.2"); } @Test From 1453f41f7ccdff910dd4505acef147287a44b31c Mon Sep 17 00:00:00 2001 From: Steve Ayers Date: Wed, 30 Apr 2025 13:50:12 -0400 Subject: [PATCH 8/8] Feedback --- src/main/java/build/buf/protovalidate/Format.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/build/buf/protovalidate/Format.java b/src/main/java/build/buf/protovalidate/Format.java index 81c3c176..cdc08f50 100644 --- a/src/main/java/build/buf/protovalidate/Format.java +++ b/src/main/java/build/buf/protovalidate/Format.java @@ -34,7 +34,6 @@ final class Format { private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); private static final char[] LOWER_HEX_ARRAY = "0123456789abcdef".toCharArray(); - private static final DecimalFormat decimalFormat = new DecimalFormat("0.#########"); /** * Format the string with a {@link ListT}. @@ -143,11 +142,11 @@ private static void formatString(StringBuilder builder, Val val) { TypeEnum type = val.type().typeEnum(); if (type == TypeEnum.Bool) { builder.append(val.booleanValue()); - } else if (type == TypeEnum.String) { + } else if (type == TypeEnum.String || type == TypeEnum.Int || type == TypeEnum.Uint) { builder.append(val.value()); } else if (type == TypeEnum.Bytes) { builder.append(new String((byte[]) val.value(), StandardCharsets.UTF_8)); - } else if (type == TypeEnum.Int || type == TypeEnum.Uint || type == TypeEnum.Double) { + } else if (type == TypeEnum.Double) { formatDecimal(builder, val); } else if (type == TypeEnum.Duration) { formatDuration(builder, val); @@ -205,7 +204,8 @@ private static void formatDuration(StringBuilder builder, Val val) { double totalSeconds = duration.getSeconds() + (duration.getNanos() / 1_000_000_000.0); - builder.append(decimalFormat.format(totalSeconds)); + DecimalFormat formatter = new DecimalFormat("0.#########"); + builder.append(formatter.format(totalSeconds)); builder.append("s"); } @@ -239,6 +239,7 @@ private static void formatHex(StringBuilder builder, Val val, char[] digits) { * @param val the value to format. */ private static void formatDecimal(StringBuilder builder, Val val) { - builder.append(decimalFormat.format(val.value())); + DecimalFormat formatter = new DecimalFormat("0.#########"); + builder.append(formatter.format(val.value())); } }