package org.zalando.riptide.stream; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.JavaType; import java.io.IOException; import java.io.UncheckedIOException; import java.util.Spliterator; import java.util.function.Consumer; final class StreamSpliterator<T> implements Spliterator<T> { private final JavaType type; private final JsonParser parser; private final boolean isNotStreamOfArrays; StreamSpliterator(final JavaType type, final JsonParser parser) { this.type = type; this.parser = parser; this.isNotStreamOfArrays = !type.isArrayType() && !type.isCollectionLikeType(); } @Override public boolean tryAdvance(final Consumer<? super T> action) { try { final JsonToken token = parser.nextToken(); if (token == null) { return false; } if (isNotStreamOfArrays && skipArrayTokens(token)) { return false; } final T value = parser.getCodec().readValue(parser, type); action.accept(value); return true; } catch (final IOException e) { throw new UncheckedIOException(e); } } private boolean skipArrayTokens(final JsonToken token) throws IOException { switch (token) { case START_ARRAY: parser.nextToken(); return false; case END_ARRAY: parser.nextToken(); return true; default: return false; } } @Override public Spliterator<T> trySplit() { return null; } @Override public long estimateSize() { return Long.MAX_VALUE; } @Override public int characteristics() { return ORDERED | IMMUTABLE; } }