diff options
-rw-r--r-- | vespajlib/src/main/java/ai/vespa/json/Json.java | 27 | ||||
-rw-r--r-- | vespajlib/src/test/java/ai/vespa/json/JsonTest.java | 39 |
2 files changed, 64 insertions, 2 deletions
diff --git a/vespajlib/src/main/java/ai/vespa/json/Json.java b/vespajlib/src/main/java/ai/vespa/json/Json.java index fef6e2e988e..99ce9290be2 100644 --- a/vespajlib/src/main/java/ai/vespa/json/Json.java +++ b/vespajlib/src/main/java/ai/vespa/json/Json.java @@ -16,9 +16,13 @@ import java.util.Iterator; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.Set; import java.util.function.BiConsumer; +import java.util.function.BinaryOperator; import java.util.function.Consumer; -import java.util.stream.Collectors; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collector; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -161,7 +165,8 @@ public class Json implements Iterable<Json> { private void requirePresent() { if (isMissing()) throw createMissingMemberException(); } private InvalidJsonException createInvalidTypeException(Type... expected) { - var expectedTypesString = Arrays.stream(expected).map(this::toString).collect(Collectors.joining("' or '", "'", "'")); + var expectedTypesString = Arrays.stream(expected).map(this::toString) + .collect(java.util.stream.Collectors.joining("' or '", "'", "'")); var pathString = path.isEmpty() ? "JSON" : "JSON member '%s'".formatted(path); return new InvalidJsonException( "Expected %s to be a %s but got '%s'" @@ -222,6 +227,10 @@ public class Json implements Iterable<Json> { SlimeUtils.addValue(json.inspector, cursor); return this; } public Builder.Array add(Json.Builder builder) { return add(builder.build()); } + /** Add all values from {@code array} to this array. */ + public Builder.Array addAll(Json.Builder.Array array) { + SlimeUtils.copyArray(array.cursor, cursor); return this; + } /** Note: does not return {@code this}! */ public Builder.Array addArray() { return new Array(cursor.addArray()); } @@ -267,4 +276,18 @@ public class Json implements Iterable<Json> { public Cursor slimeCursor() { return cursor; } public Json build() { return Json.of(cursor); } } + + public static class Collectors { + private Collectors() {} + /** @param accumululator Specify one of the 'add' overloads from {@link Builder.Array} */ + public static <T> Collector<T, Json.Builder.Array, Json> toArray(BiConsumer<Builder.Array, T> accumululator) { + return new Collector<T, Builder.Array, Json>() { + @Override public Supplier<Builder.Array> supplier() { return Json.Builder.Array::newArray; } + @Override public BiConsumer<Builder.Array, T> accumulator() { return accumululator; } + @Override public BinaryOperator<Builder.Array> combiner() { return Builder.Array::addAll; } + @Override public Function<Builder.Array, Json> finisher() { return Builder.Array::build; } + @Override public Set<Characteristics> characteristics() { return Set.of(); } + }; + } + } } diff --git a/vespajlib/src/test/java/ai/vespa/json/JsonTest.java b/vespajlib/src/test/java/ai/vespa/json/JsonTest.java index 51b64637fd8..f6ca4aa7199 100644 --- a/vespajlib/src/test/java/ai/vespa/json/JsonTest.java +++ b/vespajlib/src/test/java/ai/vespa/json/JsonTest.java @@ -2,6 +2,10 @@ package ai.vespa.json; import org.junit.jupiter.api.Test; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -130,4 +134,39 @@ class JsonTest { .toJson(true); assertEquals(expected, json); } + + @Test + void add_all() { + var expected = + """ + [ + 1, + 2, + 3, + 4, + 5, + 6 + ] + """; + var json = Json.Builder.newArray() + .addAll(Json.Builder.Array.newArray().add(1).add(2).add(3)) + .add(4) + .addAll(Json.Builder.Array.newArray().add(5)) + .add(6) + .build() + .toJson(true); + assertEquals(expected, json); + } + + @Test + void collectors() { + var expected = Json.Builder.Array.newArray() + .add(1).add(2).add(3).add(4).add(5).add(6) + .build() + .toJson(false); + var actual = Stream.of(1, 2, 3, 4, 5, 6) + .collect(Json.Collectors.toArray(Json.Builder.Array::add)) + .toJson(false); + assertEquals(expected, actual); + } } |