1 package io.atlassian.fugue.extensions.step;
2
3 import io.atlassian.fugue.Try;
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 Try} 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(Try)}
14 *
15 * @param <A> The type of the first defined value
16 * @see Steps for usage examples
17 * @see Try
18 * @since 4.7.0
19 */
20 public final class TryStep1<A> {
21
22 private final Try<A> try1;
23
24 TryStep1(Try<A> try1) {
25 this.try1 = try1;
26 }
27
28 /**
29 * Apply the provided function with the previous Step results.
30 * <p>
31 * Internally this will perform a {@link Try#flatMap(Function)} and the result
32 * 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> TryStep2<A, B> then(Function<? super A, Try<B>> functor) {
40 Try<B> try2 = try1.flatMap(functor);
41 return new TryStep2<>(try1, try2);
42 }
43
44 /**
45 * Apply the provided supplier with the previous Step results.
46 * <p>
47 * Internally this will perform a {@link Try#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> TryStep2<A, B> then(Supplier<Try<B>> supplier) {
59 Try<B> either2 = try1.flatMap(value1 -> supplier.get());
60 return new TryStep2<>(try1, either2);
61 }
62
63 /**
64 * Apply the provided predicate with the previous step results.
65 * <p>
66 * If the predicate is not satisfied then the unsatisfiedSupplier is used to
67 * populate the failure value that will prevent any further steps evaluation.
68 *
69 * @param predicate The check that must be satisfied by contained values
70 * @param unsatisfiedSupplier Provide the value to populate the failure if not
71 * satisfied
72 * @return This step class with either the same last step value, or changed to
73 * a failure
74 */
75 public TryStep1<A> filter(Predicate<? super A> predicate, Supplier<Exception> unsatisfiedSupplier) {
76 Try<A> filterTry1 = try1.filterOrElse(predicate, unsatisfiedSupplier);
77 return new TryStep1<>(filterTry1);
78 }
79
80 /**
81 * Terminating step expression, that will provide the previous steps to this
82 * function and return the result as a <code>Success</code>
83 *
84 * @param functor The yield function to map on previous values
85 * @param <Z> The type for the returned result
86 * @return A Try containing this result as success or failure
87 */
88 public <Z> Try<Z> yield(Function<? super A, Z> functor) {
89 return try1.map(functor);
90 }
91
92 }