Skip to content

Commit b58d27c

Browse files
authored
GH-87 Add enum support. Better unit tests. (#87)
1 parent e4a5962 commit b58d27c

File tree

14 files changed

+201
-52
lines changed

14 files changed

+201
-52
lines changed

litecommands-core/src/main/java/dev/rollczi/litecommands/argument/ParameterHandler.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
public interface ParameterHandler {
66

77
default boolean canHandle(Class<?> type, Parameter parameter) {
8-
return type.equals(parameter.getType());
8+
return parameter.getType().equals(type);
99
}
1010

1111
default boolean canHandleAssignableFrom(Class<?> type, Parameter parameter) {
12-
return type.isAssignableFrom(parameter.getType());
12+
return parameter.getType().isAssignableFrom(type);
1313
}
1414

1515
}

litecommands-core/src/main/java/dev/rollczi/litecommands/argument/block/BlockArgument.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,14 @@ public Option<String> getSchematic(Block annotation) {
4949
return Option.of(annotation.value());
5050
}
5151

52+
@Override
53+
public boolean canHandle(Class<?> type, Parameter parameter) {
54+
return true;
55+
}
56+
57+
@Override
58+
public boolean canHandleAssignableFrom(Class<?> type, Parameter parameter) {
59+
return true;
60+
}
61+
5262
}

litecommands-core/src/main/java/dev/rollczi/litecommands/argument/option/OptionArgument.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public boolean canHandle(Class<?> type, Parameter parameter) {
8787
@Override
8888
public boolean canHandleAssignableFrom(Class<?> type, Parameter parameter) {
8989
return OptionUtils.extractOptionType(parameter)
90-
.map(type::isAssignableFrom)
90+
.map(paramType -> paramType.isAssignableFrom(type))
9191
.orElseGet(false);
9292
}
9393

litecommands-core/src/main/java/dev/rollczi/litecommands/handle/ExecuteResultHandler.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import dev.rollczi.litecommands.command.execute.ExecuteResult;
44
import dev.rollczi.litecommands.command.LiteInvocation;
5-
import dev.rollczi.litecommands.scheme.Scheme;
65
import dev.rollczi.litecommands.scheme.SchemeFormat;
76
import dev.rollczi.litecommands.scheme.SchemeGenerator;
87
import dev.rollczi.litecommands.shared.MapUtil;
@@ -39,7 +38,7 @@ public void handle(SENDER sender, LiteInvocation invocation, ExecuteResult resul
3938
}
4039

4140
Class<?> type = object.getClass();
42-
Option<Handler<SENDER, ?>> handlerOpt = MapUtil.findByKeyAssignableFrom(type, this.handlers);
41+
Option<Handler<SENDER, ?>> handlerOpt = MapUtil.findByAssignableFromKey(type, this.handlers);
4342

4443
if (handlerOpt.isEmpty()) {
4544
Redirector<?, ?> forwarding = this.redirectors.get(type);
@@ -49,7 +48,7 @@ public void handle(SENDER sender, LiteInvocation invocation, ExecuteResult resul
4948
}
5049

5150
Object to = handleForwarding(forwarding, object);
52-
Handler<SENDER, ?> handler = MapUtil.findByKeyAssignableFrom(to.getClass(), this.handlers)
51+
Handler<SENDER, ?> handler = MapUtil.findByAssignableFromKey(to.getClass(), this.handlers)
5352
.orThrow(() -> new IllegalStateException("Missing result handler for type " + type + " or for redirected type " + to.getClass()));
5453

5554
this.handle(handler, sender, invocation, to);

litecommands-core/src/main/java/dev/rollczi/litecommands/implementation/ArgumentsRegistry.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@
66

77
import java.lang.annotation.Annotation;
88
import java.lang.reflect.Parameter;
9+
import java.util.ArrayList;
910
import java.util.HashMap;
11+
import java.util.List;
1012
import java.util.Map;
13+
import java.util.Set;
1114

1215
class ArgumentsRegistry<SENDER> {
1316

litecommands-core/src/main/java/dev/rollczi/litecommands/implementation/LiteCommandFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ private CommandState createState(Object instance) {
8181

8282
for (Annotation annotation : sectionClass.getAnnotations()) {
8383
for (FactoryAnnotationResolver<? extends Annotation> resolver : annotationResolvers) {
84-
if (!annotation.annotationType().isAssignableFrom(resolver.getAnnotationClass())) {
84+
if (!annotation.annotationType().equals(resolver.getAnnotationClass())) {
8585
continue;
8686
}
8787

@@ -100,7 +100,7 @@ private CommandState createState(Object instance) {
100100

101101
for (Annotation annotation : method.getAnnotations()) {
102102
for (FactoryAnnotationResolver<? extends Annotation> resolver : annotationResolvers) {
103-
if (!annotation.annotationType().isAssignableFrom(resolver.getAnnotationClass())) {
103+
if (!annotation.annotationType().equals(resolver.getAnnotationClass())) {
104104
continue;
105105
}
106106

litecommands-core/src/main/java/dev/rollczi/litecommands/implementation/LiteFactory.java

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package dev.rollczi.litecommands.implementation;
22

33
import dev.rollczi.litecommands.LiteCommandsBuilder;
4+
import dev.rollczi.litecommands.argument.Arg;
5+
import dev.rollczi.litecommands.argument.ArgumentContext;
6+
import dev.rollczi.litecommands.argument.ParameterHandler;
7+
import dev.rollczi.litecommands.argument.SingleArgument;
48
import dev.rollczi.litecommands.argument.block.Block;
59
import dev.rollczi.litecommands.argument.block.BlockArgument;
610
import dev.rollczi.litecommands.argument.flag.Flag;
@@ -9,25 +13,32 @@
913
import dev.rollczi.litecommands.argument.joiner.JoinerArgument;
1014
import dev.rollczi.litecommands.argument.simple.OneArgument;
1115
import dev.rollczi.litecommands.command.LiteInvocation;
16+
import dev.rollczi.litecommands.command.MatchResult;
1217
import dev.rollczi.litecommands.command.amount.Between;
1318
import dev.rollczi.litecommands.command.amount.Max;
1419
import dev.rollczi.litecommands.command.amount.Min;
1520
import dev.rollczi.litecommands.command.amount.Required;
1621
import dev.rollczi.litecommands.command.execute.Execute;
1722
import dev.rollczi.litecommands.command.permission.ExecutedPermission;
18-
import dev.rollczi.litecommands.command.permission.ExecutedPermissions;
1923
import dev.rollczi.litecommands.command.permission.LitePermissions;
2024
import dev.rollczi.litecommands.command.permission.Permission;
21-
import dev.rollczi.litecommands.command.permission.Permissions;
2225
import dev.rollczi.litecommands.command.section.Section;
23-
import dev.rollczi.litecommands.handle.Redirector;
26+
import dev.rollczi.litecommands.command.sugesstion.Suggestion;
2427
import dev.rollczi.litecommands.platform.LiteSender;
2528
import dev.rollczi.litecommands.scheme.Scheme;
29+
import dev.rollczi.litecommands.shared.EnumUtil;
2630
import panda.std.Blank;
2731
import panda.std.Option;
2832
import panda.std.Result;
2933

34+
import java.lang.annotation.ElementType;
35+
import java.lang.annotation.RetentionPolicy;
36+
import java.lang.reflect.Parameter;
37+
import java.util.Arrays;
38+
import java.util.Collections;
39+
import java.util.List;
3040
import java.util.function.Supplier;
41+
import java.util.stream.Collectors;
3142

3243
import static dev.rollczi.litecommands.argument.simple.OneArgument.create;
3344
import static dev.rollczi.litecommands.command.sugesstion.Suggestion.of;
@@ -59,6 +70,39 @@ public final class LiteFactory {
5970
private LiteFactory() {
6071
}
6172

73+
private static class EnumArgument<SENDER> implements SingleArgument<SENDER, Arg>, ParameterHandler {
74+
75+
@Override
76+
public MatchResult match(LiteInvocation invocation, ArgumentContext<Arg> context, String argument) {
77+
return EnumUtil.parse(context.parameter().getType(), argument)
78+
.fold(MatchResult::matchedSingle, (exception) -> MatchResult.notMatched());
79+
}
80+
81+
@Override
82+
public List<Suggestion> suggestion(LiteInvocation invocation, Parameter parameter, Arg annotation) {
83+
Object[] enumConstants = parameter.getType().getEnumConstants();
84+
85+
if (enumConstants == null) {
86+
return Collections.emptyList();
87+
}
88+
89+
return Arrays.stream(enumConstants)
90+
.map(Object::toString)
91+
.map(Suggestion::of)
92+
.collect(Collectors.toList());
93+
}
94+
95+
@Override
96+
public boolean canHandleAssignableFrom(Class<?> type, Parameter parameter) {
97+
return Enum.class.isAssignableFrom(parameter.getType());
98+
}
99+
100+
}
101+
102+
private static <T> Result<T, Blank> parse(Supplier<T> parse) {
103+
return Result.attempt(NumberFormatException.class, parse::get).mapErrToBlank();
104+
}
105+
62106
public static <SENDER> LiteCommandsBuilder<SENDER> builder(Class<SENDER> senderType) {
63107
return LiteCommandsBuilderImpl.builder(senderType)
64108
.configureFactory(factory -> {
@@ -96,6 +140,8 @@ public static <SENDER> LiteCommandsBuilder<SENDER> builder(Class<SENDER> senderT
96140
.argument(char.class, CHARACTER_ARG)
97141
.argument(Character.class, CHARACTER_ARG)
98142

143+
.argument(Arg.class, Enum.class, new EnumArgument<>())
144+
99145
.redirectResult(Scheme.class, String.class, scheme -> String.join(System.lineSeparator(), scheme.getSchemes()))
100146
.redirectResult(LitePermissions.class, String.class, scheme -> String.join(System.lineSeparator(), scheme.getPermissions()))
101147

@@ -105,8 +151,4 @@ public static <SENDER> LiteCommandsBuilder<SENDER> builder(Class<SENDER> senderT
105151
.contextualBind(senderType, (sender, invocation) -> Result.ok(sender));
106152
}
107153

108-
private static <T> Result<T, Blank> parse(Supplier<T> parse) {
109-
return Result.attempt(NumberFormatException.class, parse::get).mapErrToBlank();
110-
}
111-
112154
}

litecommands-core/src/main/java/dev/rollczi/litecommands/implementation/injector/InjectorContextProcessor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Option<?> extract(Parameter parameter, Invocation<SENDER> invocation) {
4242

4343
Map<Class<?>, Contextual<SENDER, ?>> binds = this.settings.getContextualBinds();
4444

45-
return MapUtil.findByKeyAssignableFrom(type, binds)
45+
return MapUtil.findByAssignableFromKey(type, binds)
4646
.map(contextual -> contextual.extract(invocation.handle(), invocation))
4747
.<Object>map(result -> result.orThrow(LiteException::new))
4848
.orElse(() -> this.extract(parameter));
@@ -57,7 +57,7 @@ Option<Object> extract(Parameter parameter) {
5757
Class<?> type = parameter.getType();
5858
Map<Class<?>, TypeBind<?>> binds = this.settings.getTypeBinds();
5959

60-
return MapUtil.findByKeyAssignableFrom(type, binds)
60+
return MapUtil.findByAssignableFromKey(type, binds)
6161
.map(typeBind -> typeBind.extract(parameter));
6262
}
6363

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package dev.rollczi.litecommands.shared;
2+
3+
import panda.std.Result;
4+
5+
public final class EnumUtil {
6+
7+
private EnumUtil() {}
8+
9+
@SuppressWarnings("unchecked")
10+
public static Result<Enum<?>, Exception> parse(Class<?> type, String argument) {
11+
return Result.attempt(Exception.class, () -> Enum.valueOf((Class<? extends Enum>) type, argument));
12+
}
13+
14+
}

litecommands-core/src/main/java/dev/rollczi/litecommands/shared/MapUtil.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ public final class MapUtil {
88

99
private MapUtil() {}
1010

11-
public static <E> Option<E> findByKeyAssignableFrom(Class<?> type, Map<Class<?>, E> map) {
12-
E handler = map.get(type);
11+
public static <E> Option<E> findByAssignableFromKey(Class<?> type, Map<Class<?>, E> map) {
12+
E element = map.get(type);
1313

14-
if (handler != null) {
15-
return Option.of(handler);
14+
if (element != null) {
15+
return Option.of(element);
1616
}
1717

1818
for (Map.Entry<Class<?>, E> entry : map.entrySet()) {

0 commit comments

Comments
 (0)