add prototype choices implementation
This commit is contained in:
		| @@ -0,0 +1,5 @@ | ||||
| package net.tomatentum.marinara.interaction.annotation; | ||||
|  | ||||
| public @interface AutoComplete { | ||||
|      | ||||
| } | ||||
| @@ -0,0 +1,5 @@ | ||||
| package net.tomatentum.marinara.interaction.commands; | ||||
|  | ||||
| public interface ChoiceValueProvider<T> { | ||||
|     T getChoiceValue(); | ||||
| } | ||||
| @@ -0,0 +1,74 @@ | ||||
| package net.tomatentum.marinara.interaction.commands; | ||||
|  | ||||
| import java.lang.reflect.InvocationTargetException; | ||||
| import java.lang.reflect.Method; | ||||
| import java.lang.reflect.ParameterizedType; | ||||
| import java.lang.reflect.Type; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
|  | ||||
| import io.leangen.geantyref.AnnotationFormatException; | ||||
| import io.leangen.geantyref.GenericTypeReflector; | ||||
| import io.leangen.geantyref.TypeFactory; | ||||
| import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOptionChoice; | ||||
|  | ||||
| public record EnumChoices(Class<? extends Enum<?>> enumClass, ChoiceType type, SlashCommandOptionChoice[] choices) { | ||||
|  | ||||
|     private static Method method; | ||||
|  | ||||
|     static { | ||||
|         try { | ||||
|             method = ChoiceValueProvider.class.getMethod("getChoiceValue"); | ||||
|         } catch (NoSuchMethodException | SecurityException e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static EnumChoices of(Class<? extends Enum<?>> enumClass) { | ||||
|         if (!ChoiceValueProvider.class.isAssignableFrom(enumClass)) | ||||
|             throw new IllegalArgumentException("Provided class needs to implement the ChoiceValueProvider interface."); | ||||
|         ChoiceType type = parseChoiceType(enumClass); | ||||
|         SlashCommandOptionChoice[] choices = parseChoices(enumClass, type); | ||||
|         return new EnumChoices(enumClass, type, choices); | ||||
|     } | ||||
|  | ||||
|     private static ChoiceType parseChoiceType(Class<? extends Enum<?>> enumClass) { | ||||
|         ParameterizedType type = (ParameterizedType) GenericTypeReflector.getExactSuperType(enumClass, ChoiceValueProvider.class); | ||||
|         Type typeParam = type.getActualTypeArguments()[0]; | ||||
|  | ||||
|         if (!(typeParam instanceof Class<?>)) | ||||
|             throw new IllegalArgumentException("ChoiceValueProvider need either a String or Number type parameter."); | ||||
|  | ||||
|         if (String.class.isAssignableFrom((Class<?>) typeParam)) | ||||
|             return ChoiceType.String; | ||||
|         else if (Number.class.isAssignableFrom((Class<?>) typeParam)) | ||||
|             return ChoiceType.Number; | ||||
|         else | ||||
|             throw new IllegalArgumentException("ChoiceValueProvider need either a String or Number type parameter."); | ||||
|     } | ||||
|  | ||||
|     private static SlashCommandOptionChoice[] parseChoices(Class<? extends Enum<?>> enumClass, ChoiceType type) { | ||||
|         Enum<? extends Enum<?>>[] constants = enumClass.getEnumConstants(); | ||||
|         List<SlashCommandOptionChoice> choices = new ArrayList<>(); | ||||
|         for (Enum<? extends Enum<?>> enumInstance : constants) { | ||||
|             Object value; | ||||
|             try { | ||||
|                 value = method.invoke(enumInstance); | ||||
|                 if (type.equals(ChoiceType.String)) | ||||
|                     choices.add(TypeFactory.annotation(SlashCommandOptionChoice.class, Map.of("name", enumInstance.name(), "stringValue", value))); | ||||
|                 else if (type.equals(ChoiceType.Number)) | ||||
|                     choices.add(TypeFactory.annotation(SlashCommandOptionChoice.class, Map.of("name", enumInstance.name(), "longValue", value))); | ||||
|             } catch (IllegalAccessException | InvocationTargetException | AnnotationFormatException e) { | ||||
|                 e.printStackTrace(); | ||||
|                 return null; | ||||
|             } | ||||
|         } | ||||
|         return choices.toArray(new SlashCommandOptionChoice[0]); | ||||
|     } | ||||
|  | ||||
|     public static enum ChoiceType { | ||||
|         String, | ||||
|         Number | ||||
|     } | ||||
| } | ||||
| @@ -2,6 +2,7 @@ package net.tomatentum.marinara.interaction.commands; | ||||
|  | ||||
| import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; | ||||
| import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption; | ||||
| import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOptionChoice; | ||||
| import net.tomatentum.marinara.interaction.commands.annotation.SubCommand; | ||||
| import net.tomatentum.marinara.interaction.commands.annotation.SubCommandGroup; | ||||
|  | ||||
| @@ -11,6 +12,13 @@ public record ExecutableSlashCommandDefinition( | ||||
|     SubCommandGroup subCommandGroup,  | ||||
|     SlashCommandOption[] options) { | ||||
|  | ||||
|     public static SlashCommandOptionChoice[] getActualChoices(SlashCommandOption option) { | ||||
|         SlashCommandOptionChoice[] choices = option.choices(); | ||||
|         if (choices.length <= 0) | ||||
|             choices = EnumChoices.of(option.choiceEnum()).choices(); | ||||
|         return choices; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public final boolean equals(Object o) { | ||||
|         if (!(o instanceof ExecutableSlashCommandDefinition)) | ||||
|   | ||||
| @@ -14,4 +14,10 @@ public @interface SlashCommandOption { | ||||
|     public String description() default ""; | ||||
|     public SlashCommandOptionType type() default SlashCommandOptionType.STRING; | ||||
|     public boolean required() default false; | ||||
|     public SlashCommandOptionChoice[] choices() default {}; | ||||
|     public Class<? extends Enum<?>> choiceEnum() default PlaceHolderEnum.class; | ||||
|  | ||||
|     public static enum PlaceHolderEnum { | ||||
|  | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,7 @@ | ||||
| package net.tomatentum.marinara.interaction.commands.annotation; | ||||
|  | ||||
| public @interface SlashCommandOptionChoice { | ||||
|     public String name(); | ||||
|     public long longValue() default Long.MAX_VALUE; | ||||
|     public String stringValue() default ""; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user