2626import java .util .Optional ;
2727import java .util .concurrent .CompletableFuture ;
2828import java .util .concurrent .CompletionException ;
29+ import java .util .function .Function ;
2930import org .apiguardian .api .API ;
3031import org .checkerframework .checker .nullness .qual .NonNull ;
3132import org .incendo .cloud .exception .handling .ExceptionController ;
@@ -115,6 +116,49 @@ private ArgumentParseResult() {
115116 return CompletableFuture .completedFuture (this );
116117 }
117118
119+ /**
120+ * Returns a future resulting from applying {@code mapper} to the parsed value,
121+ * or a completed future with the same failure as this result.
122+ *
123+ * @param mapper mapper
124+ * @param <O> new result value type
125+ * @return new result future
126+ */
127+ public abstract <O > @ NonNull CompletableFuture <ArgumentParseResult <O >> flatMapSuccessFuture (
128+ @ NonNull Function <T , CompletableFuture <ArgumentParseResult <O >>> mapper
129+ );
130+
131+ /**
132+ * Returns a success future resulting from applying {@code mapper} to the parsed value and
133+ * wrapping in {@link #success(Object)}, or a completed future with the same failure as this result.
134+ *
135+ * @param mapper mapper
136+ * @param <O> new result value type
137+ * @return new result future
138+ */
139+ public abstract <O > @ NonNull CompletableFuture <ArgumentParseResult <O >> mapSuccessFuture (
140+ @ NonNull Function <T , CompletableFuture <O >> mapper
141+ );
142+
143+ /**
144+ * Returns the result from applying {@code mapper} to the parsed value,
145+ * or the same failure as this result.
146+ *
147+ * @param mapper mapper
148+ * @param <O> new result value type
149+ * @return new result
150+ */
151+ public abstract <O > @ NonNull ArgumentParseResult <O > flatMapSuccess (@ NonNull Function <T , ArgumentParseResult <O >> mapper );
152+
153+ /**
154+ * Returns the result from applying {@code mapper} to the parsed value and
155+ * wrapping in {@link #success(Object)}, or the same failure as this result.
156+ *
157+ * @param mapper mapper
158+ * @param <O> new result value type
159+ * @return new result
160+ */
161+ public abstract <O > @ NonNull ArgumentParseResult <O > mapSuccess (@ NonNull Function <T , O > mapper );
118162
119163 private static final class ParseSuccess <T > extends ArgumentParseResult <T > {
120164
@@ -136,6 +180,32 @@ private ParseSuccess(final @NonNull T value) {
136180 public @ NonNull Optional <Throwable > failure () {
137181 return Optional .empty ();
138182 }
183+
184+ @ Override
185+ public <O > @ NonNull CompletableFuture <ArgumentParseResult <O >> flatMapSuccessFuture (
186+ final @ NonNull Function <T , CompletableFuture <ArgumentParseResult <O >>> mapper
187+ ) {
188+ return mapper .apply (this .value );
189+ }
190+
191+ @ Override
192+ public <O > @ NonNull CompletableFuture <ArgumentParseResult <O >> mapSuccessFuture (
193+ final @ NonNull Function <T , CompletableFuture <O >> mapper
194+ ) {
195+ return mapper .apply (this .value ).thenApply (ArgumentParseResult ::success );
196+ }
197+
198+ @ Override
199+ public <O > @ NonNull ArgumentParseResult <O > flatMapSuccess (
200+ final @ NonNull Function <T , ArgumentParseResult <O >> mapper
201+ ) {
202+ return mapper .apply (this .value );
203+ }
204+
205+ @ Override
206+ public <O > @ NonNull ArgumentParseResult <O > mapSuccess (final @ NonNull Function <T , O > mapper ) {
207+ return ArgumentParseResult .success (mapper .apply (this .value ));
208+ }
139209 }
140210
141211 private static final class ParseFailure <T > extends ArgumentParseResult <T > {
@@ -158,5 +228,34 @@ private ParseFailure(final @NonNull Throwable failure) {
158228 public @ NonNull Optional <Throwable > failure () {
159229 return Optional .of (this .failure );
160230 }
231+
232+ @ Override
233+ public <O > @ NonNull CompletableFuture <ArgumentParseResult <O >> flatMapSuccessFuture (
234+ final @ NonNull Function <T , CompletableFuture <ArgumentParseResult <O >>> mapper
235+ ) {
236+ return CompletableFuture .completedFuture (this .self ());
237+ }
238+
239+ @ Override
240+ public <O > @ NonNull CompletableFuture <ArgumentParseResult <O >> mapSuccessFuture (
241+ final @ NonNull Function <T , CompletableFuture <O >> mapper
242+ ) {
243+ return CompletableFuture .completedFuture (this .self ());
244+ }
245+
246+ @ Override
247+ public <O > @ NonNull ArgumentParseResult <O > flatMapSuccess (final @ NonNull Function <T , ArgumentParseResult <O >> mapper ) {
248+ return this .self ();
249+ }
250+
251+ @ Override
252+ public <O > @ NonNull ArgumentParseResult <O > mapSuccess (final @ NonNull Function <T , O > mapper ) {
253+ return this .self ();
254+ }
255+
256+ @ SuppressWarnings ("unchecked" )
257+ private <O > @ NonNull ArgumentParseResult <O > self () {
258+ return (ArgumentParseResult <O >) this ;
259+ }
161260 }
162261}
0 commit comments