Skip to content

Commit 6f08ae2

Browse files
authored
feat(core): Add helpers for mapping ArgumentParseResults (#745)
Add helpers for mapping ArgumentParseResults fixes #738 closes #739
1 parent 611a55d commit 6f08ae2

File tree

2 files changed

+101
-7
lines changed

2 files changed

+101
-7
lines changed

cloud-core/src/main/java/org/incendo/cloud/parser/ArgumentParseResult.java

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.util.Optional;
2727
import java.util.concurrent.CompletableFuture;
2828
import java.util.concurrent.CompletionException;
29+
import java.util.function.Function;
2930
import org.apiguardian.api.API;
3031
import org.checkerframework.checker.nullness.qual.NonNull;
3132
import 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
}

cloud-core/src/main/java/org/incendo/cloud/parser/ArgumentParser.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,7 @@ public interface ArgumentParser<C, T> extends SuggestionProviderHolder<C> {
133133
final @NonNull BiFunction<CommandContext<C>, T, CompletableFuture<ArgumentParseResult<O>>> mapper
134134
) {
135135
requireNonNull(mapper, "mapper");
136-
return this.flatMap((ctx, orig) -> {
137-
if (orig.failure().isPresent()) {
138-
return ArgumentParseResult.failureFuture(orig.failure().get());
139-
}
140-
return mapper.apply(ctx, orig.parsedValue().get());
141-
});
136+
return this.flatMap((ctx, result) -> result.flatMapSuccessFuture(value -> mapper.apply(ctx, value)));
142137
}
143138

144139
/**
@@ -154,7 +149,7 @@ public interface ArgumentParser<C, T> extends SuggestionProviderHolder<C> {
154149
final @NonNull BiFunction<CommandContext<C>, T, CompletableFuture<O>> mapper
155150
) {
156151
requireNonNull(mapper, "mapper");
157-
return this.flatMapSuccess((ctx, orig) -> mapper.apply(ctx, orig).thenApply(ArgumentParseResult::success));
152+
return this.flatMap((ctx, result) -> result.mapSuccessFuture(value -> mapper.apply(ctx, value)));
158153
}
159154

160155
/**

0 commit comments

Comments
 (0)