/** * Construct an Ior that contains a single value extracted from the supplied reactive-streams Publisher * <pre> * {@code * ReactiveSeq<Integer> stream = ReactiveSeq.of(1,2,3); Ior<Throwable,Integer> future = Ior.fromPublisher(stream); //Ior[1] * * } * </pre> * * @param pub Publisher to extract value from * @return Ior populated from Publisher */ public static <T> Ior<Throwable, T> fromPublisher(final Publisher<T> pub) { final ValueSubscriber<T> sub = ValueSubscriber.subscriber(); pub.subscribe(sub); return sub.toEither() .toIor(); }
/** * A flattening transformation operation that takes the first value from the returned Publisher. * <pre> * {@code * Future.ofResult(1).map(i->i+2).mergeMap(i->Flux.just(()->i*3,20); * //Future[9] * * }</pre> * * @param mapper transformation function * @return MonadicValue */ default <R> MonadicValue<R> mergeMap(final Function<? super T, ? extends Publisher<? extends R>> mapper) { return this.flatMap(a -> { final Publisher<? extends R> publisher = mapper.apply(a); final ValueSubscriber<R> sub = ValueSubscriber.subscriber(); publisher.subscribe(sub); final Maybe<R> maybe = sub.toMaybe(); return maybe.fold(in->unit(in),__->emptyUnit()); }); }
public static <T> ValueSubscriber<T> subscriber() { return new ValueSubscriber<>( () -> { }); }
/** * Construct a Right Either from the supplied publisher * <pre> * {@code * ReactiveSeq<Integer> stream = ReactiveSeq.of(1,2,3); Either<Throwable,Integer> future = Either.fromPublisher(stream); //Either[1] * * } * </pre> * @param pub Publisher to construct an Either from * @return Either constructed from the supplied Publisher */ public static <T> Either<Throwable, T> fromPublisher(final Publisher<T> pub) { final ValueSubscriber<T> sub = ValueSubscriber.subscriber(); pub.subscribe(sub); return sub.toLazyEither(); }
/** * Construct a Future asynchronously that contains a single value extracted from the supplied reactive-streams Publisher * * * <pre> * {@code * ReactiveSeq<Integer> stream = ReactiveSeq.of(1,2,3); Future<Integer> future = Future.fromPublisher(stream,ex); //Future[1] * * } * </pre> * * * @param pub Publisher to extract value from * @param ex Executor to extract value on * @return Future populated asyncrhonously from Publisher */ public static <T> Future<T> fromPublisher(final Publisher<T> pub, final Executor ex) { final ValueSubscriber<T> sub = ValueSubscriber.subscriber(); pub.subscribe(sub); return sub.toFutureAsync(ex); }
@Test public void iorPublisherTest(){ ValueSubscriber<Integer> sub = ValueSubscriber.subscriber(); Ior.right(1) .subscribe(sub); Ior<Throwable,Integer> maybe = sub.toIor(); assertThat(maybe.toOptional().get(),equalTo(1)); } @Test
final ValueSubscriber<V> sub = ValueSubscriber.subscriber(); final LazyImmutable<Boolean> requested = LazyImmutable.def(); final Option<Eval<Maybe<V>>> nested = get(key).peek(a -> a.stream() .map(a -> Eval.always(() -> { if (requested.isSet()) { sub.requestOne(); } else { requested.setOnce(true); final Maybe<V> res = sub.toMaybe(); return res; }));
/** * Extact one value from the selected pipe or an zero Maybe if it doesn't exist. Currently only Adapter's and not Publishers * are managed by Pipes so Publisher errors are not propagated (@see {@link Pipes#oneValue(Object)} or @see {@link Pipes#oneOrError(Object)} is better at the moment. * * <pre> * {@code * Queue<String> q = new Queue<>(); pipes.register("hello", q); pipes.push("hello", "world"); pipes.push("hello", "world2"); pipes.oneValueOrError("hello").getValue(); //Try["world"] * } * </pre> * * @param key : Adapter identifier * @return */ @Deprecated //errors aren't propagated across Adapters (at least without continuations) public Option<Try<V, Throwable>> oneValueOrError(final K key) { final ValueSubscriber<V> sub = ValueSubscriber.subscriber(); return get(key).peek(a -> a.stream() .subscribe(sub)) .map(a -> sub.toTry(Throwable.class)); }
public <X extends Throwable> Try<T, X> toTry(final Class<X>... classes) { return Try.withCatch(() -> throwingGet(), classes); }
@Test public void iorPublisherTest(){ ValueSubscriber<Integer> sub = ValueSubscriber.subscriber(); Ior.right(1) .subscribe(sub); Ior<Throwable,Integer> maybe = sub.toIor(); assertThat(maybe.toOptional().get(),equalTo(1)); } @Test
final ValueSubscriber<V> sub = ValueSubscriber.subscriber(); final LazyImmutable<Boolean> requested = LazyImmutable.def(); return get(key).peek(a -> a.stream() .map(a -> Eval.always(() -> { if (requested.isSet()) { sub.requestOne(); } else { requested.setOnce(true); final Maybe<V> res = sub.toMaybe();
/** * Construct a Right Either from the supplied publisher * <pre> * {@code * ReactiveSeq<Integer> stream = ReactiveSeq.of(1,2,3); Either<Throwable,Integer> future = Either.fromPublisher(stream); //Either[1] * * } * </pre> * @param pub Publisher to construct an Either from * @return Either constructed from the supplied Publisher */ public static <T> Either<Throwable, T> fromPublisher(final Publisher<T> pub) { final ValueSubscriber<T> sub = ValueSubscriber.subscriber(); pub.subscribe(sub); return sub.toLazyEither(); }
/** * Construct a Future asynchronously that contains a single value extracted from the supplied reactive-streams Publisher * * * <pre> * {@code * ReactiveSeq<Integer> stream = ReactiveSeq.of(1,2,3); Future<Integer> future = Future.fromPublisher(stream,ex); //Future[1] * * } * </pre> * * * @param pub Publisher to extract value from * @param ex Executor to extract value on * @return Future populated asyncrhonously from Publisher */ public static <T> Future<T> fromPublisher(final Publisher<T> pub, final Executor ex) { final ValueSubscriber<T> sub = ValueSubscriber.subscriber(); pub.subscribe(sub); return sub.toFutureAsync(ex); }
/** * Extact one value from the selected pipe or an zero Maybe if it doesn't exist. Currently only Adapter's and not Publishers * are managed by Pipes so Publisher errors are not propagated (@see {@link Pipes#oneValue(Object)} or @see {@link Pipes#oneOrError(Object)} is better at the moment. * * <pre> * {@code * Queue<String> q = new Queue<>(); pipes.register("hello", q); pipes.push("hello", "world"); pipes.push("hello", "world2"); pipes.oneValueOrError("hello",Throwable.class).getValue(); //Try["world"] * } * </pre> * * @param key * @param classes * @return */ @Deprecated //errors aren't propagated across Adapters (at least without continuations) public <X extends Throwable> Option<Try<V, X>> oneValueOrError(final K key, final Class<X>... classes) { final ValueSubscriber<V> sub = ValueSubscriber.subscriber(); return get(key).peek(a -> a.stream() .subscribe(sub)) .map(a -> sub.toTry(classes)); }
public Future<T> toFutureAsync(final Executor ex) { return Future.of(()->orElse(null),ex); } }
public <X extends Throwable> Try<T, X> toTry(final Class<X>... classes) { return Try.withCatch(() -> throwingGet(), classes); }
@Override public LazyEither<Throwable,T> findFirstOrError(){ return LazyEither.fromLazy(Eval.later(()->{ ValueSubscriber<T> valueSubscriber = ValueSubscriber.subscriber(); subscribe(valueSubscriber); return LazyEither.fromEither(valueSubscriber.toEither()); })); }
@Test public void maybePublisherTest(){ ValueSubscriber<Integer> sub = ValueSubscriber.subscriber(); Maybe.of(1) .subscribe(sub); Maybe<Integer> maybe = sub.toMaybe(); assertThat(maybe.toOptional().get(),equalTo(1)); } @Test
@Test public void iorPublisherErrorTest(){ ValueSubscriber<Integer> sub = ValueSubscriber.subscriber(); Ior.<Integer,Integer>left(1) .subscribe(sub); Ior<Throwable,Integer> xor = sub.toIor(); assertThat(xor.swap().orElse(null),instanceOf(NoSuchElementException.class)); } @Test