package it.tdlight.utils; import io.vertx.core.AsyncResult; import io.vertx.core.Handler; import io.vertx.core.Promise; import io.vertx.core.Vertx; import it.tdlight.jni.TdApi; import it.tdlight.tdlibsession.td.TdError; import it.tdlight.tdlibsession.td.TdResult; import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.function.BiConsumer; import java.util.function.Consumer; import org.reactivestreams.Subscription; import org.warp.commonutils.concurrency.future.CompletableFutureUtils; import reactor.core.CoreSubscriber; import reactor.core.publisher.Mono; import reactor.core.publisher.MonoSink; import reactor.core.publisher.SynchronousSink; import reactor.util.context.Context; public class MonoUtils { public static Handler> toHandler(SynchronousSink sink) { return event -> { if (event.succeeded()) { if (event.result() == null) { sink.complete(); } else { sink.next(Objects.requireNonNull(event.result())); } } else { sink.error(event.cause()); } }; } public static Handler> toHandler(MonoSink sink) { return event -> { if (event.succeeded()) { if (event.result() == null) { sink.success(); } else { sink.success(Objects.requireNonNull(event.result())); } } else { sink.error(event.cause()); } }; } public static SynchronousSink toSink(Context context, Promise promise) { return PromiseSink.of(context, promise); } public static BiConsumer> executeBlockingSink(Vertx vertx, BiConsumer> handler) { return (value, sink) -> { vertx.executeBlocking((Promise finished) -> { handler.accept(value, PromiseSink.of(sink.currentContext(), finished)); }, toHandler(sink)); }; } public static Mono executeBlocking(Vertx vertx, Consumer> action) { return Mono.create((MonoSink sink) -> { vertx.executeBlocking((Promise finished) -> { action.accept(toSink(sink.currentContext(), finished)); }, toHandler(sink)); }); } public static Mono executeAsFuture(Consumer>> action) { return Mono.fromFuture(() -> { return CompletableFutureUtils.getCompletableFuture(() -> { var resultFuture = new CompletableFuture(); action.accept(handler -> { if (handler.failed()) { resultFuture.completeExceptionally(handler.cause()); } else { resultFuture.complete(handler.result()); } }); return resultFuture; }); }); } public static CoreSubscriber toSubscriber(Promise promise) { return new CoreSubscriber() { @Override public void onSubscribe(Subscription s) { s.request(1); } @Override public void onNext(T t) { promise.complete(t); } @Override public void onError(Throwable t) { promise.fail(t); } @Override public void onComplete() { promise.tryComplete(); } }; } public static void orElseThrowFuture(TdResult value, SynchronousSink> sink) { if (value.succeeded()) { sink.next(CompletableFuture.completedFuture(value.result())); } else { sink.next(CompletableFuture.failedFuture(new TdError(value.cause().code, value.cause().message))); } } public static void orElseThrow(TdResult value, SynchronousSink sink) { if (value.succeeded()) { sink.next(value.result()); } else { sink.complete(); //sink.error(new TdError(value.cause().code, value.cause().message)); } } }