io.vertx.reactivex.SingleHelper Maven / Gradle / Ivy
package io.vertx.reactivex;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.core.type.TypeReference;
import io.reactivex.Single;
import io.reactivex.SingleObserver;
import io.reactivex.SingleTransformer;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.Promise;
import io.vertx.core.buffer.Buffer;
import io.vertx.reactivex.impl.AsyncResultSingle;
import io.vertx.reactivex.impl.SingleUnmarshaller;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* @author Julien Viet
*/
public class SingleHelper {
/**
* Returns a {@link Single} that, when subscribed, uses the provided {@code handler} to adapt a callback-based asynchronous method.
*
* For example:
*
{@code
* io.vertx.core.Vertx vertx = Vertx.vertx();
* Single deploymentId = SingleHelper.toSingle(handler -> vertx.deployVerticle("org.acme.MyVerticle", handler));
* }
*
* This is useful when using RxJava without the Vert.x Rxified API or your own asynchronous methods.
*
* The asynchronous method result must not be {@code null}, as an RxJava 2 {@link Single} does not allow {@code null} values.
*
* @param handler the code executed when the returned {@link Single} is subscribed
*/
public static Single toSingle(Consumer>> handler) {
return AsyncResultSingle.toSingle(handler);
}
/**
* Adapts an Vert.x {@code Handler>} to an RxJava2 {@link SingleObserver}.
*
* The returned observer can be subscribed to an {@link Single#subscribe(SingleObserver)}.
*
* @param handler the handler to adapt
* @return the observer
*/
public static SingleObserver toObserver(Handler> handler) {
AtomicBoolean completed = new AtomicBoolean();
return new SingleObserver() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onSuccess(@NonNull T item) {
if (completed.compareAndSet(false, true)) {
handler.handle(Future.succeededFuture(item));
}
}
@Override
public void onError(Throwable error) {
if (completed.compareAndSet(false, true)) {
handler.handle(Future.failedFuture(error));
}
}
};
}
/**
* Adapts an RxJava2 {@code Single} to a Vert.x {@link Future}.
*
* The single will be immediately subscribed and the returned future will
* be updated with the result of the single.
*
* @param single the single to adapt
* @return the future
*/
public static Future toFuture(Single single) {
Promise promise = Promise.promise();
single.subscribe(promise::complete, promise::fail);
return promise.future();
}
/**
* Like {@link SingleHelper#toFuture(Single)} but with an {@code adapter} of the result.
*/
public static Future toFuture(Single single, Function adapter) {
return toFuture(single.map(adapter::apply));
}
public static SingleTransformer unmarshaller(Class mappedType) {
return new SingleUnmarshaller<>(java.util.function.Function.identity(), mappedType);
}
public static SingleTransformer unmarshaller(TypeReference mappedTypeRef) {
return new SingleUnmarshaller<>(java.util.function.Function.identity(), mappedTypeRef);
}
public static SingleTransformer unmarshaller(Class mappedType, ObjectCodec mapper) {
return new SingleUnmarshaller<>(java.util.function.Function.identity(), mappedType, mapper);
}
public static SingleTransformer unmarshaller(TypeReference mappedTypeRef, ObjectCodec mapper) {
return new SingleUnmarshaller<>(java.util.function.Function.identity(), mappedTypeRef, mapper);
}
}