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