1 package io.atlassian.fugue.extensions.step;
2
3 import java.util.Optional;
4 import java.util.function.Function;
5 import java.util.function.Predicate;
6 import java.util.function.Supplier;
7
8 /**
9 * The first step of the {@link Optional} type.
10 * <p>
11 * This class is not intended to be contructed manually, and should only be used
12 * as part of a {@link Steps} chain, started by {@link Steps#begin(Optional)}
13 *
14 * @param <A> The type of the first defined value
15 * @see Steps for usage examples
16 * @see Optional
17 * @since 4.7.0
18 */
19 @SuppressWarnings("OptionalUsedAsFieldOrParameterType") public final class OptionalStep1<A> {
20
21 private final Optional<A> optional1;
22
23 OptionalStep1(Optional<A> optional1) {
24 this.optional1 = optional1;
25 }
26
27 /**
28 * Apply the provided function with the previous Step results.
29 * <p>
30 * Internally this will perform a {@link Optional#flatMap(Function)} and the
31 * result will become the next step value.
32 *
33 * @param functor The functor to be applied as a flatMap with the previous
34 * step
35 * @param <B> The right hand side type of the next step result
36 * @return The next step class
37 */
38 public <B> OptionalStep2<A, B> then(Function<? super A, Optional<B>> functor) {
39 Optional<B> option2 = optional1.flatMap(functor);
40 return new OptionalStep2<>(optional1, option2);
41 }
42
43 /**
44 * Apply the provided supplier with the previous Step results.
45 * <p>
46 * Internally this will perform a {@link Optional#flatMap(Function)} and the
47 * supplier will become the next step value.
48 * <p>
49 * This is different to {@link #then(Function)} in that the previous step
50 * results are not provided for the new step evaluation.
51 *
52 * @param supplier The supplier to provide the result of the flatMap with the
53 * previous step.
54 * @param <B> The type of the next step result
55 * @return The next step class
56 */
57 public <B> OptionalStep2<A, B> then(Supplier<Optional<B>> supplier) {
58 Optional<B> Optional = optional1.flatMap(value1 -> supplier.get());
59 return new OptionalStep2<>(optional1, Optional);
60 }
61
62 /**
63 * Apply the provided predicate with the previous step results.
64 *
65 * @param predicate The check that must be satisfied by contained values
66 * @return This step class with either the same last step value, or changed to
67 * empty
68 */
69 public OptionalStep1<A> filter(Predicate<? super A> predicate) {
70 Optional<A> filterOptional1 = optional1.filter(predicate);
71 return new OptionalStep1<>(filterOptional1);
72 }
73
74 /**
75 * Terminating step expression, that will provide the previous steps to this
76 * function and return the result as a <code>of</code>
77 *
78 * @param functor The yield function to map on previous values
79 * @param <Z> The type for the returned result
80 * @return An Optional containing this result or empty
81 */
82 public <Z> Optional<Z> yield(Function<? super A, Z> functor) {
83 return optional1.map(functor);
84 }
85
86 }