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

mutiny.zero.internal.MapOperator Maven / Gradle / Ivy

Go to download

Mutiny Zero is a minimal API for creating reactive-streams compliant publishers

There is a newer version: 1.1.1
Show newest version
package mutiny.zero.internal;

import java.util.Objects;
import java.util.concurrent.Flow.Processor;
import java.util.concurrent.Flow.Publisher;
import java.util.concurrent.Flow.Subscriber;
import java.util.concurrent.Flow.Subscription;
import java.util.function.Function;

public class MapOperator implements Publisher {

    private final Publisher upstream;
    private final Function mapper;

    public MapOperator(Publisher upstream, Function mapper) {
        this.upstream = upstream;
        this.mapper = mapper;
    }

    @Override
    public void subscribe(Subscriber subscriber) {
        upstream.subscribe(new MapProcessor(subscriber));
    }

    private class MapProcessor implements Processor, Subscription {

        private final Subscriber downstream;
        private Subscription subscription;
        private volatile boolean cancelled = false;

        public MapProcessor(Subscriber downstream) {
            this.downstream = downstream;
        }

        @Override
        public void subscribe(Subscriber subscriber) {

        }

        @Override
        public void onSubscribe(Subscription subscription) {
            this.subscription = subscription;
            downstream.onSubscribe(this);
        }

        @Override
        public void onNext(I i) {
            if (cancelled) {
                return;
            }
            O res;
            try {
                res = Objects.requireNonNull(mapper.apply(i));
            } catch (Exception e) {
                subscription.cancel();
                onError(e);
                return;
            }
            downstream.onNext(res);
        }

        @Override
        public void onError(Throwable throwable) {
            if (cancelled) {
                return;
            }
            cancelled = true;
            downstream.onError(throwable);
        }

        @Override
        public void onComplete() {
            if (cancelled) {
                return;
            }
            cancelled = true;
            downstream.onComplete();
        }

        @Override
        public void request(long n) {
            if (cancelled) {
                return;
            }
            subscription.request(n);
        }

        @Override
        public void cancel() {
            if (cancelled) {
                return;
            }
            cancelled = true;
            subscription.cancel();
        }
    }
}