Skip to content

Commit

Permalink
Add string bounds for slash commands (#45)
Browse files Browse the repository at this point in the history
* Add string length

* Throw if `@Length` is used on a non STRING option type

* Throw if `@LongRange`/`@DoubleRange` is used on a non INTEGER/NUMBER option type

* Update docs
  • Loading branch information
freya022 authored Sep 17, 2022
1 parent 80f6a2f commit fa53ee7
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

/**
* Allows setting minimum and maximum values on the specified {@link AppOption}
* <br><b>This is only for floating point number types !</b>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.freya02.botcommands.api.application.slash.annotations;

import com.freya02.botcommands.api.application.annotations.AppOption;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Allows setting minimum and maximum string length on the specified {@link AppOption}
* <br><b>This is only for string types !</b>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Length {
/**
* @return The minimum value of this parameter (included)
*/
int min() default 1;

/**
* @return The maximum value of this parameter (included)
*/
int max() default OptionData.MAX_STRING_OPTION_LENGTH;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

/**
* Allows setting minimum and maximum values on the specified {@link AppOption}
* <br><b>This is only for integer types !</b>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.freya02.botcommands.api.application.slash.DefaultValueSupplier;
import com.freya02.botcommands.api.application.slash.annotations.DoubleRange;
import com.freya02.botcommands.api.application.slash.annotations.Length;
import com.freya02.botcommands.api.application.slash.annotations.LongRange;
import com.freya02.botcommands.api.parameters.SlashParameterResolver;
import com.freya02.botcommands.api.prefixed.annotations.TextOption;
Expand All @@ -10,6 +11,7 @@
import gnu.trove.map.TLongObjectMap;
import gnu.trove.map.hash.TLongObjectHashMap;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;

import java.lang.reflect.Parameter;
Expand All @@ -18,6 +20,7 @@

public class SlashCommandParameter extends ApplicationCommandVarArgParameter<SlashParameterResolver> {
private final Number minValue, maxValue;
private final int minLength, maxLength;
private final EnumSet<ChannelType> channelTypes = EnumSet.noneOf(ChannelType.class);
private final TLongObjectMap<DefaultValueSupplier> defaultOptionSupplierMap = new TLongObjectHashMap<>();

Expand All @@ -29,11 +32,19 @@ public SlashCommandParameter(Parameter parameter, int index) {

final LongRange longRange = ReflectionUtils.getLongRange(parameter);
if (longRange != null) {
if (getResolver() == null || getResolver().getOptionType() != OptionType.INTEGER) {
throw new IllegalStateException("Cannot use @" + LongRange.class.getSimpleName() + " on a option that doesn't accept an integer");
}

minValue = longRange.from();
maxValue = longRange.to();
} else {
final DoubleRange doubleRange = ReflectionUtils.getDoubleRange(parameter);
if (doubleRange != null) {
if (getResolver() == null || getResolver().getOptionType() != OptionType.NUMBER) {
throw new IllegalStateException("Cannot use @" + DoubleRange.class.getSimpleName() + " on a option that doesn't accept a floating point number");
}

minValue = doubleRange.from();
maxValue = doubleRange.to();
} else {
Expand All @@ -47,6 +58,19 @@ public SlashCommandParameter(Parameter parameter, int index) {
}
}

final Length length = parameter.getAnnotation(Length.class);
if (length != null) {
if (getResolver() == null || getResolver().getOptionType() != OptionType.STRING) {
throw new IllegalStateException("Cannot use @" + Length.class.getSimpleName() + " on a option that doesn't accept a string");
}

minLength = length.min();
maxLength = length.max();
} else {
minLength = 1;
maxLength = OptionData.MAX_STRING_OPTION_LENGTH;
}

Collections.addAll(channelTypes, AnnotationUtils.getEffectiveChannelTypes(parameter));
}

Expand All @@ -62,6 +86,14 @@ public Number getMaxValue() {
return maxValue;
}

public int getMinLength() {
return minLength;
}

public int getMaxLength() {
return maxLength;
}

public TLongObjectMap<DefaultValueSupplier> getDefaultOptionSupplierMap() {
return defaultOptionSupplierMap;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ public static List<OptionData> getMethodOptions(@NotNull BContext context, @Null
} else if (optionType == OptionType.NUMBER) {
data.setMinValue(parameter.getMinValue().doubleValue());
data.setMaxValue(parameter.getMaxValue().doubleValue());
} else if (optionType == OptionType.STRING) {
data.setRequiredLength(parameter.getMinLength(), parameter.getMaxLength());
}

if (applicationOptionData.hasAutocompletion()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.freya02.botcommands.test.commands.slash;

import com.freya02.botcommands.api.application.ApplicationCommand;
import com.freya02.botcommands.api.application.annotations.AppOption;
import com.freya02.botcommands.api.application.slash.GuildSlashEvent;
import com.freya02.botcommands.api.application.slash.annotations.JDASlashCommand;
import com.freya02.botcommands.api.application.slash.annotations.Length;

public class SlashLength extends ApplicationCommand {
@JDASlashCommand(name = "length")
public void onSlashLength(GuildSlashEvent event, @AppOption @Length(max = 6) String inviteCode) {
event.reply("Invite code: " + inviteCode).queue();
}
}

0 comments on commit fa53ee7

Please sign in to comment.