
net.pincette.rs.LambdaSubscriber Maven / Gradle / Ivy
package net.pincette.rs;
import static net.pincette.util.Util.rethrow;
import static net.pincette.util.Util.tryToDoRethrow;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.Flow.Subscriber;
import java.util.concurrent.Flow.Subscription;
import java.util.function.Function;
import net.pincette.function.ConsumerWithException;
import net.pincette.function.RunnableWithException;
/**
* Provides constructors to which lambdas can be given. It requests values from the received
* subscription one by one.
*
* @param the parameterized type.
* @author Werner Donn\u00e9
* @since 1.0
*/
public class LambdaSubscriber implements Subscriber {
private final RunnableWithException complete;
private final ConsumerWithException error;
private final ConsumerWithException next;
private final Function> nextComplete;
private final ConsumerWithException subscribe;
private Subscription subscription;
public LambdaSubscriber(final ConsumerWithException next) {
this(next, null, null, null, null);
}
public LambdaSubscriber(
final ConsumerWithException next, final RunnableWithException complete) {
this(next, null, complete, null, null);
}
public LambdaSubscriber(
final ConsumerWithException next,
final RunnableWithException complete,
final ConsumerWithException error) {
this(next, null, complete, error, null);
}
public LambdaSubscriber(
final ConsumerWithException next,
final RunnableWithException complete,
final ConsumerWithException error,
final ConsumerWithException subscribe) {
this(next, null, complete, error, subscribe);
}
private LambdaSubscriber(
final ConsumerWithException next,
final Function> nextComplete,
final RunnableWithException complete,
final ConsumerWithException error,
final ConsumerWithException subscribe) {
this.next = next;
this.nextComplete = nextComplete;
this.complete = complete;
this.error = error;
this.subscribe = subscribe;
}
public static Subscriber lambdaSubscriber(final ConsumerWithException next) {
return new LambdaSubscriber<>(next, null, null, null, null);
}
public static Subscriber lambdaSubscriber(
final ConsumerWithException next, final RunnableWithException complete) {
return new LambdaSubscriber<>(next, null, complete, null, null);
}
public static Subscriber lambdaSubscriber(
final ConsumerWithException next,
final RunnableWithException complete,
final ConsumerWithException error) {
return new LambdaSubscriber<>(next, null, complete, error, null);
}
public static Subscriber lambdaSubscriber(
final ConsumerWithException next,
final RunnableWithException complete,
final ConsumerWithException error,
final ConsumerWithException subscribe) {
return new LambdaSubscriber<>(next, null, complete, error, subscribe);
}
public static Subscriber lambdaSubscriberAsync(
final Function> next) {
return new LambdaSubscriber<>(null, next, null, null, null);
}
public static Subscriber lambdaSubscriberAsync(
final Function> next, final RunnableWithException complete) {
return new LambdaSubscriber<>(null, next, complete, null, null);
}
public static Subscriber lambdaSubscriberAsync(
final Function> next,
final RunnableWithException complete,
final ConsumerWithException error) {
return new LambdaSubscriber<>(null, next, complete, error, null);
}
public static Subscriber lambdaSubscriberAsync(
final Function> next,
final RunnableWithException complete,
final ConsumerWithException error,
final ConsumerWithException subscribe) {
return new LambdaSubscriber<>(null, next, complete, error, subscribe);
}
private void more() {
subscription.request(1);
}
public void onComplete() {
if (complete != null) {
tryToDoRethrow(complete);
}
}
public void onError(final Throwable t) {
if (t == null) {
throw new NullPointerException("Can't throw null.");
}
if (error != null) {
tryToDoRethrow(() -> error.accept(t));
} else {
rethrow(t);
}
}
public void onNext(final T o) {
if (o == null) {
throw new NullPointerException("Can't emit null.");
}
if (subscription != null) {
if (next != null) {
tryToDoRethrow(() -> next.accept(o));
more();
} else if (nextComplete != null) {
nextComplete.apply(o).thenRun(this::more);
} else {
more();
}
}
}
public void onSubscribe(final Subscription s) {
if (s == null) {
throw new NullPointerException("A subscription can't be null.");
}
final Monitor monitor = new Monitor(s);
if (subscription != null) {
subscription.cancel();
} else {
if (subscribe != null) {
tryToDoRethrow(() -> subscribe.accept(monitor));
}
subscription = s;
if (!monitor.cancelled && !monitor.requested) {
s.request(1);
}
}
}
private static class Monitor implements Subscription {
private final Subscription subscription;
private boolean cancelled;
private boolean requested;
private Monitor(final Subscription subscription) {
this.subscription = subscription;
}
public void cancel() {
cancelled = true;
subscription.cancel();
}
public void request(final long n) {
requested = true;
subscription.request(n);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy