package com.github.scr.j8iterables;
import com.github.scr.j8iterables.core.CloseableSpliterator;
import java.io.Closeable;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
/**
* Utilities for Streams.
*
* @author scr on 2/24/17.
*/
@SuppressWarnings("WeakerAccess")
public class J8Streams {
/**
* Inspired by
* <a href="http://doc.akka.io/docs/akka/2.4/scala/stream/stages-overview.html#unfoldResource">akka-stream</a>,
* obtain a stream from a resource that can be closed when the stream has been consumed.
*
* @param resourceSupplier Supplier of the resource
* @param resourceSpliteratorMapper Maps the resource to a spliterator
* @param resourceCloser Closes the resource
* @param characteristics spliterator characteristics
* @param parallel Whether parallel execution is possible
* @param <T> Type of the iteration elements
* @param <R> Type of the resource
* @return A Stream of T
*/
public static <T, R> Stream<T> unfoldResource(
Supplier<R> resourceSupplier,
Function<R, Spliterator<T>> resourceSpliteratorMapper,
Consumer<R> resourceCloser,
int characteristics, boolean parallel) {
return StreamSupport.stream(() -> {
R resource = resourceSupplier.get();
Spliterator<T> spliterator = resourceSpliteratorMapper.apply(resource);
return new CloseableSpliterator<>(resource, resourceCloser, spliterator);
}, characteristics, parallel);
}
/**
* Inspired by
* <a href="http://doc.akka.io/docs/akka/2.4/scala/stream/stages-overview.html#unfoldResource">akka-stream</a>,
* obtain a stream from a {@link Closeable} resource that can be closed when the stream has been consumed.
*
* @param resourceSupplier Supplier of the resource
* @param resourceSpliteratorMapper Maps the resource to a spliterator
* @param characteristics spliterator characteristics
* @param parallel Whether parallel execution is possible
* @param <T> Type of the iteration elements
* @param <R> Type of the resource
* @return A Stream of T
* @apiNote If {@link Closeable} throws an {@link java.io.IOException}, an {@link java.io.UncheckedIOException} will be thrown.
*/
public static <T, R extends Closeable> Stream<T> unfoldResource(
Supplier<R> resourceSupplier,
Function<R, Spliterator<T>> resourceSpliteratorMapper,
int characteristics, boolean parallel) {
return StreamSupport.stream(() -> {
R resource = resourceSupplier.get();
Spliterator<T> spliterator = resourceSpliteratorMapper.apply(resource);
return CloseableSpliterator.ofCloseableResource(resource, spliterator);
}, characteristics, parallel);
}
}