Skip to content

Commit

Permalink
feat(core): improve aggregate direct mappers (#720)
Browse files Browse the repository at this point in the history
  • Loading branch information
jpenilla authored Apr 11, 2024
1 parent 2b793d8 commit c34c6cc
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 63 deletions.
19 changes: 10 additions & 9 deletions cloud-core/src/main/java/org/incendo/cloud/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiFunction;
import org.apiguardian.api.API;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
Expand All @@ -46,6 +45,8 @@
import org.incendo.cloud.parser.ParserDescriptor;
import org.incendo.cloud.parser.ParserRegistry;
import org.incendo.cloud.parser.aggregate.AggregateParser;
import org.incendo.cloud.parser.aggregate.AggregateParserPairBuilder;
import org.incendo.cloud.parser.aggregate.AggregateParserTripletBuilder;
import org.incendo.cloud.parser.flag.CommandFlag;
import org.incendo.cloud.parser.flag.CommandFlagParser;
import org.incendo.cloud.parser.standard.LiteralParser;
Expand Down Expand Up @@ -1377,7 +1378,7 @@ private Builder(
final @NonNull ParserDescriptor<C, U> firstParser,
final @NonNull String secondName,
final @NonNull ParserDescriptor<C, V> secondParser,
final @NonNull BiFunction<C, Pair<U, V>, O> mapper,
final AggregateParserPairBuilder.@NonNull Mapper<C, U, V, O> mapper,
final @NonNull Description description
) {
if (this.commandManager == null) {
Expand Down Expand Up @@ -1416,7 +1417,7 @@ private Builder(
final @NonNull ParserDescriptor<C, U> firstParser,
final @NonNull String secondName,
final @NonNull ParserDescriptor<C, V> secondParser,
final @NonNull BiFunction<C, Pair<U, V>, O> mapper,
final AggregateParserPairBuilder.@NonNull Mapper<C, U, V, O> mapper,
final @NonNull Description description
) {
if (this.commandManager == null) {
Expand Down Expand Up @@ -1455,7 +1456,7 @@ private Builder(
final @NonNull ParserDescriptor<C, U> firstParser,
final @NonNull String secondName,
final @NonNull ParserDescriptor<C, V> secondParser,
final @NonNull BiFunction<C, Pair<U, V>, O> mapper,
final AggregateParserPairBuilder.@NonNull Mapper<C, U, V, O> mapper,
final @NonNull Description description
) {
if (this.commandManager == null) {
Expand Down Expand Up @@ -1494,7 +1495,7 @@ private Builder(
final @NonNull ParserDescriptor<C, U> firstParser,
final @NonNull String secondName,
final @NonNull ParserDescriptor<C, V> secondParser,
final @NonNull BiFunction<C, Pair<U, V>, O> mapper,
final AggregateParserPairBuilder.@NonNull Mapper<C, U, V, O> mapper,
final @NonNull Description description
) {
if (this.commandManager == null) {
Expand Down Expand Up @@ -1708,7 +1709,7 @@ private Builder(
final @NonNull ParserDescriptor<C, V> secondParser,
final @NonNull String thirdName,
final @NonNull ParserDescriptor<C, W> thirdParser,
final @NonNull BiFunction<C, Triplet<U, V, W>, O> mapper,
final AggregateParserTripletBuilder.@NonNull Mapper<C, U, V, W, O> mapper,
final @NonNull Description description
) {
if (this.commandManager == null) {
Expand Down Expand Up @@ -1756,7 +1757,7 @@ private Builder(
final @NonNull ParserDescriptor<C, V> secondParser,
final @NonNull String thirdName,
final @NonNull ParserDescriptor<C, W> thirdParser,
final @NonNull BiFunction<C, Triplet<U, V, W>, O> mapper,
final AggregateParserTripletBuilder.@NonNull Mapper<C, U, V, W, O> mapper,
final @NonNull Description description
) {
if (this.commandManager == null) {
Expand Down Expand Up @@ -1804,7 +1805,7 @@ private Builder(
final @NonNull ParserDescriptor<C, V> secondParser,
final @NonNull String thirdName,
final @NonNull ParserDescriptor<C, W> thirdParser,
final @NonNull BiFunction<C, Triplet<U, V, W>, O> mapper,
final AggregateParserTripletBuilder.@NonNull Mapper<C, U, V, W, O> mapper,
final @NonNull Description description
) {
if (this.commandManager == null) {
Expand Down Expand Up @@ -1852,7 +1853,7 @@ private Builder(
final @NonNull ParserDescriptor<C, V> secondParser,
final @NonNull String thirdName,
final @NonNull ParserDescriptor<C, W> thirdParser,
final @NonNull BiFunction<C, Triplet<U, V, W>, O> mapper,
final AggregateParserTripletBuilder.@NonNull Mapper<C, U, V, W, O> mapper,
final @NonNull Description description
) {
if (this.commandManager == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,6 @@ public class AggregateParserBuilder<C> {

/**
* Returns a new builder with the given {@code mapper}.
* <p>
* Use {@link #withDirectMapper(Class, AggregateResultMapper.DirectAggregateResultMapper)} if you do not want to wrap
* the result in a completable future.
*
* @param <O> the type produced by the mapper
* @param valueType the type produced by the mapper
Expand All @@ -92,7 +89,7 @@ public class AggregateParserBuilder<C> {
*/
public final <O> @NonNull MappedAggregateParserBuilder<C, O> withDirectMapper(
final @NonNull Class<O> valueType,
final AggregateResultMapper.@NonNull DirectAggregateResultMapper<C, O> mapper
final AggregateResultMapper.@NonNull DirectSuccessMapper<C, O> mapper
) {
return new MappedAggregateParserBuilder<>(this.components(), TypeToken.get(valueType), mapper);
}
Expand All @@ -109,7 +106,7 @@ public class AggregateParserBuilder<C> {
*/
public final <O> @NonNull MappedAggregateParserBuilder<C, O> withDirectMapper(
final @NonNull TypeToken<O> valueType,
final AggregateResultMapper.@NonNull DirectAggregateResultMapper<C, O> mapper
final AggregateResultMapper.@NonNull DirectSuccessMapper<C, O> mapper
) {
return new MappedAggregateParserBuilder<>(this.components(), valueType, mapper);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import io.leangen.geantyref.TypeToken;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.component.TypedCommandComponent;
import org.incendo.cloud.context.CommandContext;
Expand Down Expand Up @@ -55,9 +54,9 @@ public static <C, U, V> Mapper<C, U, V, Pair<U, V>> defaultMapper() {
/**
* Creates a new {@link AggregateParserPairBuilder} with the given components and mapper.
*
* @param first the first component
* @param second the second component
* @param mapper the mapper
* @param first the first component
* @param second the second component
* @param mapper the mapper
* @param outType the output type
*/
public AggregateParserPairBuilder(
Expand All @@ -76,8 +75,8 @@ public AggregateParserPairBuilder(
* Creates a new {@link AggregateParserPairBuilder} with the given mapper.
*
* @param outType the new output type
* @param mapper the mapper
* @param <O1> the new output type
* @param mapper the mapper
* @param <O1> the new output type
* @return a new {@link AggregateParserPairBuilder} with the given mapper
*/
public <O1> AggregateParserPairBuilder<C, U, V, O1> withMapper(
Expand All @@ -91,21 +90,15 @@ public <O1> AggregateParserPairBuilder<C, U, V, O1> withMapper(
* Creates a new {@link AggregateParserPairBuilder} with the given mapper.
*
* @param outType the new output type
* @param mapper the mapper
* @param <O1> the new output type
* @param mapper the mapper
* @param <O1> the new output type
* @return a new {@link AggregateParserPairBuilder} with the given mapper
*/
public <O1> AggregateParserPairBuilder<C, U, V, O1> withMapper(
public <O1> AggregateParserPairBuilder<C, U, V, O1> withDirectMapper(
final @NonNull TypeToken<O1> outType,
final @NonNull BiFunction<C, Pair<U, V>, O1> mapper
final Mapper.@NonNull DirectSuccessMapper<C, U, V, O1> mapper
) {
return this.withMapper(
outType,
(ctx, u, v) -> ArgumentParseResult.successFuture(mapper.apply(
ctx.sender(),
Pair.of(u, v)
))
);
return this.withMapper(outType, mapper);
}

/**
Expand All @@ -124,20 +117,60 @@ public AggregateParser<C, O> build() {
).build();
}

/**
* Helper function to create a direct success mapper.
*
* @param mapper mapper
* @param <C> command sender type
* @param <U> first component type
* @param <V> second component type
* @param <O> output type
* @return mapper
*/
static <C, U, V, O> Mapper<C, U, V, O> directMapper(final Mapper.DirectSuccessMapper<C, U, V, O> mapper) {
return mapper;
}

public interface Mapper<C, U, V, O> {

/**
* Maps the results of the child parsers to the output type.
*
* @param commandContext the command context
* @param firstResult the first result
* @param secondResult the second result
* @param firstResult the first result
* @param secondResult the second result
* @return the mapped result
*/
@NonNull CompletableFuture<ArgumentParseResult<O>> map(
@NonNull CommandContext<C> commandContext,
@NonNull U firstResult,
@NonNull V secondResult
);

interface DirectSuccessMapper<C, U, V, O> extends Mapper<C, U, V, O> {

/**
* Maps the results of the child parsers to the output type.
*
* @param commandContext the command context
* @param firstResult the first result
* @param secondResult the second result
* @return the mapped result
*/
@NonNull O mapSuccess(
@NonNull CommandContext<C> commandContext,
@NonNull U firstResult,
@NonNull V secondResult
);

@Override
default @NonNull CompletableFuture<ArgumentParseResult<O>> map(
@NonNull CommandContext<C> commandContext,
@NonNull U firstResult,
@NonNull V secondResult
) {
return ArgumentParseResult.successFuture(this.mapSuccess(commandContext, firstResult, secondResult));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import io.leangen.geantyref.TypeToken;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.component.TypedCommandComponent;
import org.incendo.cloud.context.CommandContext;
Expand Down Expand Up @@ -57,10 +56,10 @@ public static <C, U, V, Z> Mapper<C, U, V, Z, Triplet<U, V, Z>> defaultMapper()
/**
* Creates a new {@link AggregateParserTripletBuilder} with the given components and mapper.
*
* @param first the first component
* @param second the second component
* @param third the third component
* @param mapper the mapper
* @param first the first component
* @param second the second component
* @param third the third component
* @param mapper the mapper
* @param outType the output type
*/
public AggregateParserTripletBuilder(
Expand All @@ -81,8 +80,8 @@ public AggregateParserTripletBuilder(
* Creates a new {@link AggregateParserTripletBuilder} with the given mapper.
*
* @param outType the new output type
* @param mapper the mapper
* @param <O1> the new output type
* @param mapper the mapper
* @param <O1> the new output type
* @return a new {@link AggregateParserTripletBuilder} with the given mapper
*/
public <O1> AggregateParserTripletBuilder<C, U, V, Z, O1> withMapper(
Expand All @@ -96,21 +95,15 @@ public <O1> AggregateParserTripletBuilder<C, U, V, Z, O1> withMapper(
* Creates a new {@link AggregateParserTripletBuilder} with the given mapper.
*
* @param outType the new output type
* @param mapper the mapper
* @param <O1> the new output type
* @param mapper the mapper
* @param <O1> the new output type
* @return a new {@link AggregateParserTripletBuilder} with the given mapper
*/
public <O1> AggregateParserTripletBuilder<C, U, V, Z, O1> withMapper(
public <O1> AggregateParserTripletBuilder<C, U, V, Z, O1> withDirectMapper(
final @NonNull TypeToken<O1> outType,
final @NonNull BiFunction<C, Triplet<U, V, Z>, O1> mapper
final Mapper.@NonNull DirectSuccessMapper<C, U, V, Z, O1> mapper
) {
return this.withMapper(
outType,
(ctx, u, v, z) -> ArgumentParseResult.successFuture(mapper.apply(
ctx.sender(),
Triplet.of(u, v, z)
))
);
return this.withMapper(outType, mapper);
}

/**
Expand All @@ -130,15 +123,30 @@ public AggregateParser<C, O> build() {
).build();
}

/**
* Helper function to create a direct success mapper.
*
* @param mapper mapper
* @param <C> command sender type
* @param <U> first component type
* @param <V> second component type
* @param <Z> third component type
* @param <O> output type
* @return mapper
*/
static <C, U, V, Z, O> Mapper<C, U, V, Z, O> directMapper(final Mapper.DirectSuccessMapper<C, U, V, Z, O> mapper) {
return mapper;
}

public interface Mapper<C, U, V, Z, O> {

/**
* Maps the results of the child parsers to the output type.
*
* @param commandContext the command context
* @param firstResult the first result
* @param secondResult the second result
* @param thirdResult the third result
* @param firstResult the first result
* @param secondResult the second result
* @param thirdResult the third result
* @return the mapped result
*/
@NonNull CompletableFuture<ArgumentParseResult<O>> map(
Expand All @@ -147,5 +155,34 @@ public interface Mapper<C, U, V, Z, O> {
@NonNull V secondResult,
@NonNull Z thirdResult
);

interface DirectSuccessMapper<C, U, V, Z, O> extends Mapper<C, U, V, Z, O> {

/**
* Maps the results of the child parsers to the output type.
*
* @param commandContext the command context
* @param firstResult the first result
* @param secondResult the second result
* @param thirdResult the third result
* @return the mapped result
*/
@NonNull O mapSuccess(
@NonNull CommandContext<C> commandContext,
@NonNull U firstResult,
@NonNull V secondResult,
@NonNull Z thirdResult
);

@Override
default @NonNull CompletableFuture<ArgumentParseResult<O>> map(
@NonNull CommandContext<C> commandContext,
@NonNull U firstResult,
@NonNull V secondResult,
@NonNull Z thirdResult
) {
return ArgumentParseResult.successFuture(this.mapSuccess(commandContext, firstResult, secondResult, thirdResult));
}
}
}
}
Loading

0 comments on commit c34c6cc

Please sign in to comment.