All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.rouz.flo.Values Maven / Gradle / Ivy

There is a newer version: 0.0.5
Show newest version
package io.rouz.flo;

import io.rouz.flo.TaskContext.Value;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.stream.Collector;
import java.util.stream.Stream;

/**
 * Utilities for manipulating instances of {@link Value}.
 */
public final class Values {

  private Values() {
  }

  /**
   * Maps a function over two {@link Value}s returning a new {@link Value} of the result which
   * only becomes available when both inputs have completed.
   *
   * 

The returned {@link Value} will not complete until both input values have completed either * successfully or with an exception. If both inputs fail with an exception, the exception from * {@code first} will be propagated into the returned value. * * @param context The context which values are processed in * @param first The first input value * @param second The second input value * @param fn The map function * @param The type of the first input value * @param The type of the second input value * @param The type of the return value * @return A value that completes only when both inputs have completed */ public static Value mapBoth( TaskContext context, Value first, Value second, BiFunction fn) { TaskContext.Promise promise = context.promise(); BiConsumer firstComplete = (t, firstThrowable) -> { BiConsumer secondComplete = (v, secondThrowable) -> { if (firstThrowable != null) { promise.fail(firstThrowable); } else if (secondThrowable != null) { promise.fail(secondThrowable); } else { promise.set(fn.apply(t, v)); } }; second.consume(v -> secondComplete.accept(v, null)); second.onFail(e -> secondComplete.accept(null, e)); }; first.consume(t -> firstComplete.accept(t, null)); first.onFail(e -> firstComplete.accept(null, e)); return promise.value(); } /** * A {@link Collector} that collects a {@link Stream} of {@link Value}s into a {@link Value} * of a {@link List}. * *

The semantics of joining {@link Value}s is decided by this {@link TaskContext}. * * @param context The context which values are processed in * @param The inner type of the values * @return A collector for a stream of values */ public static Collector, ?, Value>> toValueList(TaskContext context) { return Collector.of( ArrayList::new, List::add, (a, b) -> { a.addAll(b); return a; }, ValueFold.inContext(context)); } }