Skip to content

Commit

Permalink
Determine on which side to put spaces in command patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
freya022 committed Dec 18, 2022
1 parent 65e8698 commit c25c4cf
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.freya02.botcommands.api.parameters.RegexParameterResolver;
import com.freya02.botcommands.internal.utils.Utils;
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -30,6 +31,11 @@ public static Pattern of(TextCommandInfo commandInfo) {
return pattern;
}

private enum SpacePosition {
LEFT,
RIGHT
}

public static class ParameterPattern {
private final Pattern pattern;
private final boolean optional;
Expand All @@ -41,15 +47,19 @@ public ParameterPattern(RegexParameterResolver resolver, boolean optional, boole
: resolver.getPattern();
}

public String toString(boolean includeSpace) {
public String toString(@Nullable SpacePosition position) {
if (optional) {
if (includeSpace) {
if (position == SpacePosition.LEFT) {
return "(?:" + "\\s+" + pattern.toString() + ")?";
} else if (position == SpacePosition.RIGHT) {
return "(?:" + pattern.toString() + "\\s+" + ")?";
} else {
return "(?:" + pattern.toString() + ")?";
}
} else {
if (includeSpace) {
if (position == SpacePosition.LEFT) {
return "\\s+" + pattern.toString();
} else if (position == SpacePosition.RIGHT) {
return pattern.toString() + "\\s+";
} else {
return pattern.toString();
Expand All @@ -62,11 +72,29 @@ public static Pattern joinPatterns(List<ParameterPattern> patterns) {
final StringBuilder builder = new StringBuilder(16 * patterns.size());
builder.append("^");

for (int i = 0, patternsSize = patterns.size(); i < patternsSize; i++) {
ParameterPattern pattern = patterns.get(i);
// The space must stick to the optional part when in between, while being the nearest from the middle point
// So if arg0 is optional, but arg1 is not, the space goes on the right part of the regex of arg0
// If arg0 is required, but arg1 is optional, the space goes on the left part of the regex of arg1
final SpacePosition[] positions = new SpacePosition[patterns.size()];
for (int i = 0; i < patterns.size() - 1; i++) {
final ParameterPattern arg0 = patterns.get(i);
final ParameterPattern arg1 = patterns.get(i + 1);

boolean includeSpace = i <= patternsSize - 2; //TODO should be positioned on left if last index
builder.append(pattern.toString(includeSpace));
if (arg0.optional && !arg1.optional) {
positions[i] = SpacePosition.RIGHT;
} else if (!arg0.optional && arg1.optional) {
positions[i + 1] = SpacePosition.LEFT;
} else if (arg0.optional /*&& arg1.optional*/) {
positions[i + 1] = SpacePosition.LEFT;
} else { //Both are required
positions[i + 1] = SpacePosition.LEFT;
}
}

for (int i = 0, patternsSize = patterns.size(); i < patternsSize; i++) {
final ParameterPattern pattern = patterns.get(i);
final SpacePosition position = positions[i];
builder.append(pattern.toString(position));
}

return Pattern.compile(builder.toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

import com.freya02.botcommands.api.BContext;
import com.freya02.botcommands.api.parameters.RegexParameterResolver;
import com.freya02.botcommands.internal.parameters.LongResolver;
import com.freya02.botcommands.internal.parameters.StringResolver;
import com.freya02.botcommands.internal.parameters.UserResolver;
import com.freya02.botcommands.internal.parameters.*;
import com.freya02.botcommands.internal.prefixed.CommandPattern;
import com.freya02.botcommands.internal.prefixed.CommandPattern.ParameterPattern;
import com.freya02.botcommands.internal.prefixed.TextCommandInfo;
Expand All @@ -14,30 +12,75 @@

import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class CommandPatternTest {
private record TestParameterPattern(RegexParameterResolver resolver, boolean optional,
boolean hasMultipleQuotable) {
public ParameterPattern toParameterPattern() {
return new ParameterPattern(resolver, optional, hasMultipleQuotable);
}
}

public static void main(String[] args) {
test1();
test2();
test3();
test4();
}

private static void test1() {
final List<ParameterPattern> patterns = List.of(
new ParameterPattern(new LibResolver(), true, false),
new ParameterPattern(new StringResolver(), false, false)
);
private static void test(List<TestParameterPattern> patterns) {
final String syntax = patterns.stream()
.map(p -> p.resolver.getClass().getSimpleName().replace("Resolver", "") + (p.optional ? "?" : ""))
.collect(Collectors.joining(" "));
System.out.println("Syntax: " + syntax);

System.out.println(CommandPattern.joinPatterns(patterns));
final Pattern pattern = CommandPattern.joinPatterns(patterns.stream().map(TestParameterPattern::toParameterPattern).toList());
System.out.println("Pattern: " + pattern);

final String exampleStr = getExampleStr(patterns);
System.out.println("Example: " + exampleStr);
System.out.println("Matches: " + pattern.asMatchPredicate().test(exampleStr));

System.out.println();
}

private static void test1() {
test(List.of(
new TestParameterPattern(new LibResolver(), true, false),
new TestParameterPattern(new StringResolver(), false, false)
));
}

private static void test2() {
final List<ParameterPattern> patterns = List.of(
new ParameterPattern(new UserResolver(), false, false),
new ParameterPattern(new LongResolver(), true, false),
new ParameterPattern(new StringResolver(), true, false)
);
test(List.of(
new TestParameterPattern(new UserResolver(), false, false),
new TestParameterPattern(new LongResolver(), true, false),
new TestParameterPattern(new StringResolver(), true, false)
));
}

private static void test3() {
test(List.of(
new TestParameterPattern(new MemberResolver(), false, false),
new TestParameterPattern(new StringResolver(), true, false)
));
}

System.out.println(CommandPattern.joinPatterns(patterns));
private static void test4() {
test(List.of(
new TestParameterPattern(new LibResolver(), true, false),
new TestParameterPattern(new StringResolver(), false, false),
new TestParameterPattern(new DoubleResolver(), true, false)
));
}

private static String getExampleStr(List<TestParameterPattern> patterns) {
return patterns.stream()
.filter(t -> !t.optional)
.map(t -> t.resolver)
.map(RegexParameterResolver::getTestExample)
.collect(Collectors.joining(" "));
}

private static class LibResolver implements RegexParameterResolver {
Expand All @@ -53,7 +96,7 @@ private static class LibResolver implements RegexParameterResolver {

@Override
public @NotNull String getTestExample() {
return null;
return "jda";
}
}
}

0 comments on commit c25c4cf

Please sign in to comment.