allow JsonArray to pretty-print in a single line when appropriate

This commit is contained in:
jbb01 2025-04-12 19:51:42 +02:00
parent 1da002ce70
commit 97892ff273
No known key found for this signature in database
GPG Key ID: 83C72CB6D5442CF1
4 changed files with 50 additions and 10 deletions

View File

@ -370,12 +370,27 @@ public record JsonArray(
}
@Override
public @NotNull String toPrettyJsonString() {
public @NotNull String toPrettyJsonString(int depth) {
if (size() < 2) return toJsonString();
var out = new StringJoiner(",\n", "[\n", "\n]");
elements().forEach(e -> out.add(indent(JsonValue.toPrettyJsonString(e))));
return out.toString();
var entries = new ArrayList<String>(elements.size());
var length = 0L;
var composite = false;
for (var element : elements) {
var string = JsonValue.toPrettyJsonString(element, depth + Util.PRETTY_PRINT_INDENT.length());
entries.add(string);
composite |= element instanceof JsonObject || element instanceof JsonArray;
length += string.length() + 2; // +2 to account for ", " and "[]"
}
if (!composite && depth + length <= Util.PRETTY_PRINT_ARRAY_MULTILINE_THRESHOLD) {
return "[" + String.join(", ", entries) + "]";
} else {
var out = new StringJoiner(",\n", "[\n", "\n]");
entries.forEach(e -> out.add(indent(e)));
return out.toString();
}
}
private static @NotNull String indent(@NotNull String string) {
@ -385,7 +400,7 @@ public record JsonArray(
Iterator<String> it = string.lines().iterator();
while (it.hasNext()) {
out.append(" ").append(it.next());
out.append(Util.PRETTY_PRINT_INDENT).append(it.next());
if (it.hasNext()) out.append('\n');
}

View File

@ -353,9 +353,14 @@ public record JsonObject(@NotNull Map<@NotNull String, @Nullable JsonValue> entr
}
@Override
public @NotNull String toPrettyJsonString() {
StringJoiner out = new StringJoiner(",\n ", "{\n ", "\n}");
entries.forEach((key, value) -> out.add(JsonString.quote(key) + ": " + indent(JsonValue.toPrettyJsonString(value))));
public @NotNull String toPrettyJsonString(int depth) {
StringJoiner out = new StringJoiner(",\n" + Util.PRETTY_PRINT_INDENT, "{\n" + Util.PRETTY_PRINT_INDENT, "\n}");
entries.forEach((key, value) -> {
var keyString = JsonString.quote(key);
var valueIdent = depth + Util.PRETTY_PRINT_INDENT.length() + keyString.length() + 3; // +3 for ": " and ","
var valueString = JsonValue.toPrettyJsonString(value, valueIdent);
out.add(keyString + ": " + indent(valueString));
});
return out.toString();
}
@ -369,7 +374,7 @@ public record JsonObject(@NotNull Map<@NotNull String, @Nullable JsonValue> entr
while (it.hasNext()) {
String next = it.next();
out.append('\n').append(it.hasNext() ? " " : " ").append(next);
out.append('\n').append(Util.PRETTY_PRINT_INDENT).append(next);
}
return out.toString();

View File

@ -24,6 +24,14 @@ public sealed interface JsonValue extends Serializable permits JsonObject, JsonA
* {@return a prettified JSON representation of this value}
*/
default @NotNull String toPrettyJsonString() {
return toPrettyJsonString(0);
}
/**
* {@return a prettified JSON representation of this value}
* @param depth indicates the depth at which this value appears (no formal definition given)
*/
default @NotNull String toPrettyJsonString(int depth) {
return toJsonString();
}
@ -40,7 +48,16 @@ public sealed interface JsonValue extends Serializable permits JsonObject, JsonA
* @param value a {@link JsonValue} (possibly {@code null})
*/
static @NotNull String toPrettyJsonString(@Nullable JsonValue value) {
return value == null ? "null" : value.toPrettyJsonString();
return toPrettyJsonString(value, 0);
}
/**
* {@return the prettified JSON representation of the given value}
* @param value a {@link JsonValue} (possibly {@code null})
* @param depth indicates the depth at which the value appears (no formal definition given)
*/
static @NotNull String toPrettyJsonString(@Nullable JsonValue value, int depth) {
return value == null ? "null" : value.toPrettyJsonString(depth);
}
/**

View File

@ -8,6 +8,9 @@ import java.util.*;
@UtilityClass
class Util {
static final @NotNull String PRETTY_PRINT_INDENT = " ";
static final int PRETTY_PRINT_ARRAY_MULTILINE_THRESHOLD = 80;
private static final @NotNull Class<?> LIST_1_2 = List.of(1).getClass();
private static final @NotNull Class<?> LIST_N = List.of(1, 2, 3).getClass();
private static final @NotNull Class<?> SUB_LIST = List.of(1, 2, 3).subList(0, 2).getClass();