Skip to content
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

Add greedy charset option to string argument #131

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
27 changes: 25 additions & 2 deletions src/main/java/com/mojang/brigadier/StringReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,24 @@ public static boolean isAllowedInUnquotedString(final char c) {
|| c == '.' || c == '+';
}

public static boolean isAllowedInUnquotedStringGreedy(final char c) {
return c != ' '
&& c != SYNTAX_DOUBLE_QUOTE
&& c != SYNTAX_SINGLE_QUOTE
&& c != SYNTAX_ESCAPE;
}

public String readUnquotedString() {
return readUnquotedString(true);
}

public String readUnquotedStringGreedy() {
return readUnquotedString(false);
}

private String readUnquotedString(boolean asciiOnly) {
final int start = cursor;
while (canRead() && isAllowedInUnquotedString(peek())) {
while (canRead() && (asciiOnly ? isAllowedInUnquotedString(peek()) : isAllowedInUnquotedStringGreedy(peek()))) {
skip();
}
return string.substring(start, cursor);
Expand Down Expand Up @@ -220,6 +235,14 @@ public String readStringUntil(char terminator) throws CommandSyntaxException {
}

public String readString() throws CommandSyntaxException {
return readString(true);
}

public String readStringGreedy() throws CommandSyntaxException {
return readString(false);
}

private String readString(boolean asciiOnly) throws CommandSyntaxException {
if (!canRead()) {
return "";
}
Expand All @@ -228,7 +251,7 @@ public String readString() throws CommandSyntaxException {
skip();
return readStringUntil(next);
}
return readUnquotedString();
return readUnquotedString(asciiOnly);
}

public boolean readBoolean() throws CommandSyntaxException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,32 @@
import java.util.Collection;

public class StringArgumentType implements ArgumentType<String> {
private final boolean greedyCharset;
private final StringType type;

private StringArgumentType(final StringType type) {
private StringArgumentType(final StringType type, final boolean greedyCharset) {
this.type = type;
this.greedyCharset = greedyCharset;
}

public static StringArgumentType word() {
return new StringArgumentType(StringType.SINGLE_WORD);
return word(false);
}

public static StringArgumentType word(boolean greedyCharset) {
return new StringArgumentType(StringType.SINGLE_WORD, greedyCharset);
}

public static StringArgumentType string() {
return new StringArgumentType(StringType.QUOTABLE_PHRASE);
return string(false);
}

public static StringArgumentType string(boolean greedyCharset) {
return new StringArgumentType(StringType.QUOTABLE_PHRASE, greedyCharset);
}

public static StringArgumentType greedyString() {
return new StringArgumentType(StringType.GREEDY_PHRASE);
return new StringArgumentType(StringType.GREEDY_PHRASE, false);
}

public static String getString(final CommandContext<?> context, final String name) {
Expand All @@ -37,16 +47,28 @@ public StringType getType() {
return type;
}

public boolean hasGreedyCharset() {
return greedyCharset;
}

@Override
public String parse(final StringReader reader) throws CommandSyntaxException {
if (type == StringType.GREEDY_PHRASE) {
final String text = reader.getRemaining();
reader.setCursor(reader.getTotalLength());
return text;
} else if (type == StringType.SINGLE_WORD) {
return reader.readUnquotedString();
if (this.greedyCharset) {
return reader.readUnquotedStringGreedy();
} else {
return reader.readUnquotedString();
}
} else {
return reader.readString();
if (this.greedyCharset) {
return reader.readStringGreedy();
} else {
return reader.readString();
}
}
}

Expand Down
58 changes: 58 additions & 0 deletions src/test/java/com/mojang/brigadier/StringReaderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,30 @@ public void readUnquotedString() throws Exception {
assertThat(reader.getRemaining(), equalTo(" world"));
}

@Test
public void readUnquotedString_strictCharset() throws Exception {
final StringReader reader = new StringReader("1+1=2 2+2=4");
assertThat(reader.readString(), equalTo("1+1"));
assertThat(reader.getRead(), equalTo("1+1"));
assertThat(reader.getRemaining(), equalTo("=2 2+2=4"));

// Should not be able to read further -- as invalid character is present
assertThat(reader.readString(), equalTo(""));
}

@Test
public void readUnquotedString_strictCharsetQuoted() throws Exception {
final StringReader reader = new StringReader("\"1+1=2\" \"2+2=4\"");
assertThat(reader.readString(), equalTo("1+1=2"));
assertThat(reader.getRead(), equalTo("\"1+1=2\""));
assertThat(reader.getRemaining(), equalTo(" \"2+2=4\""));

reader.skipWhitespace();

assertThat(reader.readString(), equalTo("2+2=4"));
assertThat(reader.getRead(), equalTo("\"1+1=2\" \"2+2=4\""));
}

@Test
public void readUnquotedString_empty() throws Exception {
final StringReader reader = new StringReader("");
Expand All @@ -148,6 +172,40 @@ public void readUnquotedString_empty_withRemaining() throws Exception {
assertThat(reader.getRemaining(), equalTo(" hello world"));
}

@Test
public void readUnquotedStringGreedy() throws Exception {
final StringReader reader = new StringReader("hello world");
assertThat(reader.readStringGreedy(), equalTo("hello"));
assertThat(reader.getRead(), equalTo("hello"));
assertThat(reader.getRemaining(), equalTo(" world"));
}

@Test
public void readUnquotedStringGreedy_strictCharset() throws Exception {
final StringReader reader = new StringReader("1+1=2 2+2=4");
assertThat(reader.readStringGreedy(), equalTo("1+1=2"));
assertThat(reader.getRead(), equalTo("1+1=2"));
assertThat(reader.getRemaining(), equalTo(" 2+2=4"));
reader.skipWhitespace();
assertThat(reader.readStringGreedy(), equalTo("2+2=4"));
}

@Test
public void readUnquotedStringGreedy_empty() throws Exception {
final StringReader reader = new StringReader("");
assertThat(reader.readUnquotedStringGreedy(), equalTo(""));
assertThat(reader.getRead(), equalTo(""));
assertThat(reader.getRemaining(), equalTo(""));
}

@Test
public void readUnquotedStringGreedy_empty_withRemaining() throws Exception {
final StringReader reader = new StringReader(" hello world");
assertThat(reader.readUnquotedStringGreedy(), equalTo(""));
assertThat(reader.getRead(), equalTo(""));
assertThat(reader.getRemaining(), equalTo(" hello world"));
}

@Test
public void readQuotedString() throws Exception {
final StringReader reader = new StringReader("\"hello world\"");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,22 @@ public class StringArgumentTypeTest {
@Mock
private CommandContextBuilder<Object> context;

@Test
public void testParseWord_greedyCharset() throws Exception {
final StringReader reader = mock(StringReader.class);
when(reader.readUnquotedStringGreedy()).thenReturn("1+1=2");
assertThat(word(true).parse(reader), equalTo("1+1=2"));
verify(reader).readUnquotedStringGreedy();
}

@Test
public void testParseString_greedyCharset() throws Exception {
final StringReader reader = mock(StringReader.class);
when(reader.readStringGreedy()).thenReturn("1+1=2 2+2=4");
assertThat(string(true).parse(reader), equalTo("1+1=2 2+2=4"));
verify(reader).readStringGreedy();
}

@Test
public void testParseWord() throws Exception {
final StringReader reader = mock(StringReader.class);
Expand Down