diff --git a/blackbox-test/src/test/java/org/example/customer/PrettyNestedTest.java b/blackbox-test/src/test/java/org/example/customer/PrettyNestedTest.java new file mode 100644 index 00000000..43c772b6 --- /dev/null +++ b/blackbox-test/src/test/java/org/example/customer/PrettyNestedTest.java @@ -0,0 +1,53 @@ +package org.example.customer; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.Instant; +import java.util.List; + +import org.junit.jupiter.api.Test; + +import io.avaje.jsonb.Json; +import io.avaje.jsonb.Jsonb; + +public class PrettyNestedTest { + @Json + public record DataContainer(String id, Instant createdAt, List apps) { + public record App( + String id, Instant createdAt, Instant updatedAt, String name, List roles) {} + } + + @Test + void testNested() { + final String pretty = + """ + { + "id": "f11177d2-ec63-3995-bb4a-c628e0d782df", + "createdAt": "1970-01-01T00:00:01Z", + "apps": [ + { + "id": "ea4959eb-64a1-309b-a580-d950964f3843", + "createdAt": "1970-01-01T00:00:01Z", + "updatedAt": "1970-01-01T00:00:01Z", + "name": "Name", + "roles": [ + "admin" + ] + }, + { + "id": "ea4959eb-64a1-309b-a580-d950964f3843", + "createdAt": "1970-01-01T00:00:01Z", + "updatedAt": "1970-01-01T00:00:01Z", + "name": "Name", + "roles": [ + "admin" + ] + } + ] + }"""; + + var type = Jsonb.instance().type(DataContainer.class); + String jsonPretty = type.toJsonPretty(type.fromJson(pretty)); + assertThat(jsonPretty).isEqualTo(pretty); + } +} diff --git a/json-core/src/main/java/io/avaje/json/stream/core/JGenerator.java b/json-core/src/main/java/io/avaje/json/stream/core/JGenerator.java index cda69a7b..0fa9fb09 100644 --- a/json-core/src/main/java/io/avaje/json/stream/core/JGenerator.java +++ b/json-core/src/main/java/io/avaje/json/stream/core/JGenerator.java @@ -64,6 +64,8 @@ class JGenerator implements JsonGenerator { private int position; private boolean pretty; private int depth; + private int arrayDepth; + private int objectDepth; private final Deque nameStack = new ArrayDeque<>(); private JsonNames currentNames; private boolean allNames; @@ -484,7 +486,7 @@ private void prefixValue() { if (lastOp == OP_END) { writeByte(COMMA); } - if (pretty && (depth > 1)) { + if (pretty && depth > 1 && objectDepth <= arrayDepth) { prettyIndent(); } lastOp = OP_END; @@ -496,12 +498,16 @@ public void pretty(boolean pretty) { } private void writeStartObject() { - if (pretty) { - depth++; - } if (lastOp == OP_END) { writeByte(COMMA); } + if (pretty) { + if (arrayDepth > 0 && arrayDepth >= objectDepth) { + prettyIndent(); + } + depth++; + objectDepth++; + } writeByte(OBJECT_START); lastOp = OP_START; } @@ -531,6 +537,7 @@ public void endObject() { } if (pretty) { depth--; + objectDepth--; prettyIndent(); } writeByte(OBJECT_END); @@ -543,6 +550,7 @@ public void startArray() { lastOp = OP_START; if (pretty) { depth++; + arrayDepth++; } } @@ -550,6 +558,7 @@ public void startArray() { public void endArray() { if (pretty) { depth--; + arrayDepth--; prettyIndent(); } writeByte(ARRAY_END); diff --git a/jsonb-generator/pom.xml b/jsonb-generator/pom.xml index a2b74234..66053b8f 100644 --- a/jsonb-generator/pom.xml +++ b/jsonb-generator/pom.xml @@ -11,7 +11,7 @@ avaje jsonb generator annotation processor generating source code json adapters for avaje-jsonb - 1.43 + 1.44-RC3