8000 Add a MapArgument to the CommandAPI by JorelAli · Pull Request #418 · CommandAPI/CommandAPI · GitHub
[go: up one dir, main page]

Skip to content

Add a MapArgument to the CommandAPI #418

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 48 commits into from
Mar 4, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
fe6f87b
Initial commit of the MapArgument
DerEchtePilz Jan 29, 2023
f12f055
Remove continue statements
DerEchtePilz Jan 29, 2023
b06ed20
Revert "Remove continue statements"
DerEchtePilz Jan 29, 2023
3274f0c
Limit the type of key values
DerEchtePilz Jan 30, 2023
43c25f6
Adds tests for float and integer keys
DerEchtePilz Jan 30, 2023
eefe64b
Fix JavaDocs of the MapArgument
DerEchtePilz Jan 30, 2023
a2a7658
Improve JavaDocs of the MapArgument
DerEchtePilz Jan 30, 2023
d10e29a
Prepare to implement suggestions
DerEchtePilz Jan 30, 2023
18adf8e
First commit of implementing suggestions (doesn't work correctly)
DerEchtePilz Feb 2, 2023
3e5023e
Fix suggestions (the suggestions, depite being correct, show up at th…
DerEchtePilz Feb 2, 2023
bbe69d9
Finish suggestions for the MapArgument
DerEchtePilz Feb 3, 2023
674d96a
Remove test command from CommandAPIMain.java
DerEchtePilz Feb 3, 2023
2fbe304
Fix MapArgument tests
DerEchtePilz Feb 3, 2023
d7b9bd5
Removes MapArgumentKeyType
DerEchtePilz Feb 3, 2023
12c9fb0
Finally make suggestions work correctly
DerEchtePilz Feb 3, 2023
483690c
Make the MapArgument return a LinkedHashMap
DerEchtePilz Feb 3, 2023
b6dedf7
Enable commandapi-bukkit-kotlin-test again
DerEchtePilz Feb 3, 2023
8cc72e0
Fix values actually being removed from the list of suggestions if all…
DerEchtePilz Feb 3, 2023
9e5869b
Refactor MapArgument#parseArgument and MapArgument#getSuggestionCode
DerEchtePilz Feb 3, 2023
574096c
More SonarCloud stuff
DerEchtePilz Feb 3, 2023
5e7fb47
Revert the latest refactoring commits and implement an enum to determ…
DerEchtePilz Feb 3, 2023
25a3c73
Throws a CommandSyntaxException if keys or values were provided which…
DerEchtePilz Feb 4, 2023
005b210
Implement tests for invalid keys and values
DerEchtePilz Feb 4, 2023
5134349
Adds tests while using withoutKeyList()/withoutValueList()
DerEchtePilz Feb 4, 2023
249d1ea
Create documentation page. Rename withKeyType() to withKeyMapper()
DerEchtePilz Feb 4, 2023
6a2f2dc
Adds documentation for the MapArgument
DerEchtePilz Feb 4, 2023
5871989
Adds a check to validate keys when building the MapArgument
DerEchtePilz Feb 4, 2023
0b826b7
Fix check that validates keys when building the MapArgument
DerEchtePilz Feb 4, 2023
aa1afed
Throw a CommandSyntaxException if duplicate values have been entered …
DerEchtePilz Feb 4, 2023
b58341b
Removes AMapArgument.java
DerEchtePilz Feb 4, 2023
081eb0b
Adds MapArgument entry to arguments.md
DerEchtePilz Feb 4, 2023
8d8dba7
Improve removing suggestions when duplicates are not allowed
DerEchtePilz Feb 5, 2023
3611281
Removes an unused field
DerEchtePilz Feb 5, 2023
01279b0
Fix documentation for the MapArgument
DerEchtePilz Feb 5, 2023
d490f2b
Fix some formatting in argument_map.md
DerEchtePilz Feb 6, 2023
037a21a
Fix MapArgument allowing incomplete maps
DerEchtePilz Feb 8, 2023
1ca3653
Does this fix a 'bug' SonarCloud is complaining about?
DerEchtePilz Feb 12, 2023
0c2205e
Use the same StringBuilder for both keyBuilder and valueBuilder
JorelAli Feb 12, 2023
1caabb6
Merge branch 'dev/dev' into dev/map-argument
DerEchtePilz Feb 17, 2023
129b2bc
Fix MapArgument#parseArgument to use the CommandArguments class
DerEchtePilz Feb 17, 2023
4f0dd4a
Adding some more tests
DerEchtePilz Feb 18, 2023
91aab9f
Implement suggestion tests for the MapArgument
DerEchtePilz Feb 24, 2023
4f75e95
Adds suggestion tests without values being removed
DerEchtePilz Feb 24, 2023
0ebb148
Catch exception that is thrown when the mapping function fails and th…
DerEchtePilz Mar 1, 2023
fb5e5b5
Adds a missing test when parsing arguments
DerEchtePilz Mar 2, 2023
03a256f
Wrap map argument syntax in a code block
JorelAli Mar 3, 2023
c8d67c8
Merge dev/dev into dev/map-argument
DerEchtePilz Mar 4, 2023
47d6c61
Merge JorelAli:dev/map-argument into dev/map-argument
DerEchtePilz Mar 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Limit the type of key values
  • Loading branch information
DerEchtePilz committed Jan 30, 2023
commit 3274f0cfc6e9924e48e957edab56668d7d3cafc8
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import dev.jorel.commandapi.wrappers.MapArgumentKeyType;

import java.util.HashMap;
import java.util.function.Function;
Expand All @@ -26,7 +27,7 @@
public class MapArgument<K, V> extends Argument<HashMap> implements GreedyArgument {

private final char delimiter;
private final Function<String, K> keyMapper;
private final Function<String, ?> keyMapper;
private final Function<String, V> valueMapper;

/**
Expand All @@ -35,12 +36,17 @@ public class MapArgument<K, V> extends Argument<HashMap> implements GreedyArgume
* @param nodeName the name to assign to this argument node
* @param delimiter This is used to separate key-value pairs
*/
MapArgument(String nodeName, char delimiter, Function<String, K> keyMapper, Function<String, V> valueMapper) {
MapArgument(String nodeName, char delimiter, MapArgumentKeyType keyType, Function<String, V> valueMapper) {
super(nodeName, StringArgumentType.greedyString());

this.delimiter = delimiter;
this.keyMapper = keyMapper;
this.valueMapper = valueMapper;

this.keyMapper = switch (keyType) {
case STRING -> (s -> s);
case INT -> (Integer::valueOf);
case FLOAT -> (Float::valueOf);
};
}

@Override
Expand All @@ -53,6 +59,7 @@ public CommandAPIArgumentType getArgumentType() {
return CommandAPIArgumentType.MAP;
}

@SuppressWarnings("unchecked")
@Override
public <Source> HashMap<K, V> parseArgument(CommandContext<Source> cmdCtx, String key, Object[] previousArgs) throws CommandSyntaxException {
String rawValues = cmdCtx.getArgument(key, String.class);
Expand All @@ -78,7 +85,7 @@ public <Source> HashMap<K, V> parseArgument(CommandContext<Source> cmdCtx, Strin
visitedCharacters.append(currentChar);
if (isAKeyBeingBuilt) {
if (currentChar == delimiter) {
mapKey = keyMapper.apply(keyBuilder.toString());
mapKey = (K) keyMapper.apply(keyBuilder.toString());

// No need to check the key here because we already know it only consists of letters

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package dev.jorel.commandapi.arguments;

import dev.jorel.commandapi.wrappers.MapArgumentKeyType;

import java.util.function.Function;

/**
* A builder to create a {@link MapArgument}
*
* @param <K>
* @param <V>
* @param <V> The type of values this map should contain
*/
public class MapArgumentBuilder<K, V> {
public class MapArgumentBuilder<V> {

private final String nodeName;
private final char delimiter;
Expand Down Expand Up @@ -39,19 +40,19 @@ public MapArgumentBuilder(String nodeName, char delimiter) {
*
* @return this map argument builder
*/
public MapArgumentBuilderValueMapper withKeyMapper(Function<String, K> keyMapper) {
return new MapArgumentBuilderValueMapper(keyMapper);
public MapArgumentBuilderValueMapper withKeyType(MapArgumentKeyType keyType) {
return new MapArgumentBuilderValueMapper(keyType);
}

/**
* An intermediary class for the {@link MapArgumentBuilder}
*/
public class MapArgumentBuilderValueMapper {

private final Function<String, K> keyMapper;
private final MapArgumentKeyType keyType;

public MapArgumentBuilderValueMapper(Function<String, K> keyMapper) {
this.keyMapper = keyMapper;
public MapArgumentBuilderValueMapper(MapArgumentKeyType keyType) {
this.keyType = keyType;
}

/**
Expand Down Expand Up @@ -81,8 +82,12 @@ public MapArgumentBuilderFinished(Function<String, V> valueMapper) {
*
* @return a new {@link MapArgument}
*/
public MapArgument<K, V> build() {
return new MapArgument<>(nodeName, delimiter, keyMapper, valueMapper);
public MapArgument<?, V> build() {
return switch (keyType) {
case STRING -> new MapArgument<String, V>(nodeName, delimiter, keyType, valueMapper);
case FLOAT -> new MapArgument< EDB7 Float, V>(nodeName, delimiter, keyType, valueMapper);
case INT -> new MapArgument<Integer, V>(nodeName, delimiter, keyType, valueMapper);
};
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package dev.jorel.commandapi.wrappers;

public enum MapArgumentKeyType {
STRING,
FLOAT,
INT
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import dev.jorel.commandapi.exceptions.GreedyArgumentException;
import dev.jorel.commandapi.test.Mut;
import dev.jorel.commandapi.test.TestBase;
import dev.jorel.commandapi.wrappers.MapArgumentKeyType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -46,8 +47,8 @@ public void executionTestWithMapArgument() {
Mut<HashMap<String, String>> results = Mut.of();

new CommandAPICommand("test")
.withArguments(new MapArgumentBuilder<String, String>("map", ':')
.withKeyMapper(s -> s)
.withArguments(new MapArgumentBuilder<String>("map", ':')
.withKeyType(MapArgumentKeyType.STRING)
.withValueMapper(s -> s)
.build()
)
Expand Down Expand Up @@ -82,8 +83,8 @@ public void executionTestWithMapArgumentAndSpecialValues() {
Mut<HashMap<String, String>> results = Mut.of();

new CommandAPICommand("test")
.withArguments(new MapArgumentBuilder<String, String>("map", ':')
.withKeyMapper(s -> s)
.withArguments(new MapArgumentBuilder<String>("map", ':')
.withKeyType(MapArgumentKeyType.STRING)
.withValueMapper(s -> s)
.build()
)
Expand Down Expand Up @@ -113,8 +114,8 @@ public void exceptionTestWithMapArgument() {
// A GreedyArgumentException should be thrown when it is not the last argument.
assertThrows(GreedyArgumentException.class, () -> {
new CommandAPICommand("test")
.withArguments(new MapArgumentBuilder<String, Integer>("map", '=')
.withKeyMapper(s -> s)
.withArguments(new MapArgumentBuilder<Integer>("map", '=')
.withKeyType(MapArgumentKeyType.STRING)
.withValueMapper(Integer::valueOf)
.build()
)
Expand All @@ -124,8 +125,8 @@ public void exceptionTestWithMapArgument() {
});

new CommandAPICommand("test")
.withArguments(new MapArgumentBuilder<String, String>("map", ':')
.withKeyMapper(s -> s)
.withArguments(new MapArgumentBuilder<String>("map", ':')
.withKeyType(MapArgumentKeyType.STRING)
.withValueMapper(s -> s)
.build()
)
Expand All @@ -150,6 +151,46 @@ public void exceptionTestWithMapArgument() {
// Test without closing quotation mark
// /test map:"test1
assertCommandFailsWith(player, "test map:\"test1", "Could not parse command: A value has to end with a quotation mark! at position 10: map:\"test1<--[HERE]");

// Test without any quotation marks
// /test map:5
assertCommandFailsWith(player, "test map:5", "Could not parse command: A value has to start with a quotation mark! at position 4: map:<--[HERE]");
}

@Test
public void executionTestWithOtherKeyValuePairs() {
Mut<HashMap<String, Integer>> results = Mut.of();

new CommandAPICommand("test")
.withArguments(new MapArgumentBuilder<Integer>("map")
.withKeyType(MapArgumentKeyType.STRING)
.withValueMapper(Integer::valueOf)
.build()
)
.executesPlayer((player, args) -> {
results.set((HashMap<String, Integer>) args.get("map"));
})
.register();

PlayerMock player = server.addPlayer();

// /test map:"598"
server.dispatchCommand(player, "test map:\"598\"");
Map<String, Integer> testMap = new HashMap<>();
testMap.put("map", 598);
assertEquals(testMap, results.get());

// /test map:"598" age:"18"
server.dispatchCommand(player, "test map:\"598\" age:\"18\"");
testMap.put("age", 18);
assertEquals(testMap, results.get());

// /test map:"598" age:"18" someThirdValue:"19999"
server.dispatchCommand(player, "test map:\"598\" age:\"18\" someThirdValue:\"19999\"");
testMap.put("someThirdValue", 19999);
assertEquals(testMap, results.get());

assertNoMoreResults(results);
}

}
0