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

com.aol.cyclops.reactor.transformer.FluxTValue Maven / Gradle / Ivy

There is a newer version: 9.0.0-MI7
Show newest version
package com.aol.cyclops.reactor.transformer;

import java.util.Iterator;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

import com.aol.cyclops.control.AnyM;
import com.aol.cyclops.control.ReactiveSeq;
import com.aol.cyclops.types.IterableFoldable;
import com.aol.cyclops.types.MonadicValue;
import com.aol.cyclops.types.Traversable;
import com.aol.cyclops.types.anyM.AnyMValue;
import com.aol.cyclops.types.stream.CyclopsCollectable;

import reactor.core.publisher.Flux;

/**
 * Monad Transformer for Cyclops Streams
 * 
 * FluxT consists of an AnyM instance that in turns wraps anoter Monad type that contains an Stream
 * 
 * FluxT>>>
 * 
 * FluxT allows the deeply wrapped Stream to be manipulating within it's nested /contained context
 * @author johnmcclean
 *
 * @param 
 */
public class FluxTValue implements FluxT {

    private final AnyMValue> run;

    private FluxTValue(final AnyMValue> in) {
        this.run = (AnyMValue) in;
    }

    /**
     * @return The wrapped AnyM
     */
    public AnyMValue> unwrap() {
        return run;
    }

    public boolean isSeqPresent() {
        return !run.isEmpty();
    }

    /**
     * Peek at the current value of the Stream
     * 
     * {@code 
     *    FluxT.of(AnyM.fromStream(Arrays.asStream(10))
     *             .peek(System.out::println);
     *             
     *     //prints 10        
     * }
     * 
* * @param peek Consumer to accept current value of Stream * @return FluxT with peek call */ public FluxTValue peek(Consumer peek) { return map(a -> { peek.accept(a); return a; }); } /** * Filter the wrapped Stream *
     * {@code 
     *    FluxT.of(AnyM.fromStream(Arrays.asStream(10,11))
     *             .filter(t->t!=10);
     *             
     *     //FluxT>>
     * }
     * 
* @param test Predicate to filter the wrapped Stream * @return FluxT that applies the provided filter */ public FluxTValue filter(Predicate test) { return of(run.map(stream -> stream.filter(i -> test.test(i)))); } /** * Map the wrapped Stream * *
     * {@code 
     *  FluxT.of(AnyM.fromStream(Arrays.asStream(10))
     *             .map(t->t=t+1);
     *  
     *  
     *  //FluxT>>
     * }
     * 
* * @param f Mapping function for the wrapped Stream * @return FluxT that applies the map function to the wrapped Stream */ public FluxTValue map(Function f) { return new FluxTValue( run.map(o -> o.map(f))); } /** * Flat Map the wrapped Stream *
     * {@code 
     *  FluxT.of(AnyM.fromStream(Arrays.asStream(10))
     *             .flatMap(t->Stream.empty();
     *  
     *  
     *  //FluxT>>
     * }
     * 
* @param f FlatMap function * @return FluxT that applies the flatMap function to the wrapped Stream */ public FluxTValue flatMapT(Function> f) { return of(run.map(stream -> stream.flatMap(a -> Flux.from(f.apply(a).run.stream())) . flatMap(a -> a))); } public FluxTValue flatMap(Function> f) { return new FluxTValue( run.map(o -> o.flatMap(f))); } /** * Lift a function into one that accepts and returns an FluxT * This allows multiple monad types to add functionality to existing functions and methods * * e.g. to add iteration handling (via Stream) and nullhandling (via Optional) to an existing function *
     * {@code 
    	Function add2 = i -> i+2;
    	Function, FluxT> optTAdd2 = FluxT.lift(add2);
    	
    	Stream nums = Stream.of(1,2);
    	AnyM> stream = AnyM.fromOptional(Optional.of(nums));
    	
    	List results = optTAdd2.apply(FluxT.of(stream))
    									.unwrap()
    									.>>unwrap()
    									.get()
    									.collect(Collectors.toList());
    	//Stream.of(3,4);
     * 
     * 
     * }
* * * @param fn Function to enhance with functionality from Stream and another monad type * @return Function that accepts and returns an FluxT */ public static Function, FluxTValue> lift(Function fn) { return optTu -> optTu.map(input -> fn.apply(input)); } /** * Construct an FluxT from an AnyM that contains a monad type that contains type other than Stream * The values in the underlying monad will be mapped to Stream * * @param anyM AnyM that doesn't contain a monad wrapping an Stream * @return FluxT */ public static FluxTValue fromAnyM(AnyMValue anyM) { return of(anyM.map(Flux::just)); } /** * Create a FluxT from an AnyM that wraps a monad containing a Stream * * @param monads * @return */ public static FluxTValue of(AnyMValue> monads) { return new FluxTValue<>( monads); } public static FluxTValue of(Flux monads) { return FluxT.fromOptional(Optional.of(monads)); } public static >> FluxTValue fromValue(V monadicValue) { return of(AnyM.ofValue(monadicValue)); } public boolean isStreamPresent() { return !run.isEmpty(); } public Flux get() { return run.get(); } /* * (non-Javadoc) * * @see java.lang.Object#toString() */ public String toString() { return String.format("FluxTValue[%s]", run); } /* * (non-Javadoc) * * @see java.lang.Iterable#iterator() */ @Override public Iterator iterator() { return stream().iterator(); } /* * (non-Javadoc) * * @see * com.aol.cyclops.types.IterableFunctor#unitIterator(java.util.Iterator) */ @Override public FluxTValue unitIterator(Iterator u) { return of(run.unit(Flux.fromIterable(() -> u))); } /* * (non-Javadoc) * * @see com.aol.cyclops.types.Unit#unit(java.lang.Object) */ @Override public FluxTValue unit(T unit) { return of(run.unit(Flux.just(unit))); } @Override public ReactiveSeq stream() { return run.map(i -> ReactiveSeq.fromPublisher(i)) .stream() .flatMap(e -> e); } @Override public Flux Flux() { return Flux.from(stream()); } @Override public FluxTValue empty() { return of(run.empty()); } public static FluxTValue emptyOptional() { return FluxT.fromOptional(Optional.empty()); } @Override public AnyM> nestedFoldables() { return run.map(i -> ReactiveSeq.fromPublisher(i)); } @Override public AnyM> nestedCollectables() { return run.map(i -> ReactiveSeq.fromPublisher(i)); } @Override public FluxTValue unitAnyM(AnyM> traversable) { return of((AnyMValue) traversable.map(t -> Flux.fromIterable(t))); } @Override public AnyM> transformerStream() { return run.map(i -> ReactiveSeq.fromPublisher(i)); } @Override public int hashCode() { return run.hashCode(); } @Override public boolean equals(Object o) { if (o instanceof FluxTValue) { return run.equals(((FluxTValue) o).run); } return false; } }