Add long argument

This commit is contained in:
Earthcomputer 2018-09-26 15:32:27 +01:00 committed by Nathan Adams
parent 6a15305c3d
commit 88714288a7
5 changed files with 218 additions and 0 deletions

View file

@ -110,6 +110,23 @@ public class StringReader implements ImmutableStringReader {
} }
} }
public long readLong() throws CommandSyntaxException {
final int start = cursor;
while (canRead() && isAllowedNumber(peek())) {
skip();
}
final String number = string.substring(start, cursor);
if (number.isEmpty()) {
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.readerExpectedLong().createWithContext(this);
}
try {
return Long.parseLong(number);
} catch (final NumberFormatException ex) {
cursor = start;
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.readerInvalidLong().createWithContext(this, number);
}
}
public double readDouble() throws CommandSyntaxException { public double readDouble() throws CommandSyntaxException {
final int start = cursor; final int start = cursor;
while (canRead() && isAllowedNumber(peek())) { while (canRead() && isAllowedNumber(peek())) {

View file

@ -0,0 +1,87 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
package com.mojang.brigadier.arguments;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import java.util.Arrays;
import java.util.Collection;
public class LongArgumentType implements ArgumentType<Long> {
private static final Collection<String> EXAMPLES = Arrays.asList("0", "123", "-123");
private final long minimum;
private final long maximum;
private LongArgumentType(final long minimum, final long maximum) {
this.minimum = minimum;
this.maximum = maximum;
}
public static LongArgumentType longArg() {
return longArg(Long.MIN_VALUE);
}
public static LongArgumentType longArg(final long min) {
return longArg(min, Long.MAX_VALUE);
}
public static LongArgumentType longArg(final long min, final long max) {
return new LongArgumentType(min, max);
}
public static long getLong(final CommandContext<?> context, final String name) {
return context.getArgument(name, long.class);
}
public long getMinimum() {
return minimum;
}
public long getMaximum() {
return maximum;
}
@Override
public Long parse(final StringReader reader) throws CommandSyntaxException {
final int start = reader.getCursor();
final long result = reader.readLong();
if (result < minimum) {
reader.setCursor(start);
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.longTooLow().createWithContext(reader, result, minimum);
}
if (result > maximum) {
reader.setCursor(start);
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.longTooHigh().createWithContext(reader, result, maximum);
}
return result;
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (!(o instanceof LongArgumentType)) return false;
final LongArgumentType that = (LongArgumentType) o;
return maximum == that.maximum && minimum == that.minimum;
}
@Override
public int hashCode() {
return 31 * Long.hashCode(minimum) + Long.hashCode(maximum);
}
@Override
public String toString() {
if (minimum == Long.MIN_VALUE && maximum == Long.MAX_VALUE) {
return "longArg()";
} else if (maximum == Long.MAX_VALUE) {
return "longArg(" + minimum + ")";
} else {
return "longArg(" + minimum + ", " + maximum + ")";
}
}
}

View file

@ -16,6 +16,10 @@ public interface BuiltInExceptionProvider {
Dynamic2CommandExceptionType integerTooHigh(); Dynamic2CommandExceptionType integerTooHigh();
Dynamic2CommandExceptionType longTooLow();
Dynamic2CommandExceptionType longTooHigh();
DynamicCommandExceptionType literalIncorrect(); DynamicCommandExceptionType literalIncorrect();
SimpleCommandExceptionType readerExpectedStartOfQuote(); SimpleCommandExceptionType readerExpectedStartOfQuote();
@ -30,6 +34,10 @@ public interface BuiltInExceptionProvider {
SimpleCommandExceptionType readerExpectedInt(); SimpleCommandExceptionType readerExpectedInt();
DynamicCommandExceptionType readerInvalidLong();
SimpleCommandExceptionType readerExpectedLong();
DynamicCommandExceptionType readerInvalidDouble(); DynamicCommandExceptionType readerInvalidDouble();
SimpleCommandExceptionType readerExpectedDouble(); SimpleCommandExceptionType readerExpectedDouble();

View file

@ -15,6 +15,9 @@ public class BuiltInExceptions implements BuiltInExceptionProvider {
private static final Dynamic2CommandExceptionType INTEGER_TOO_SMALL = new Dynamic2CommandExceptionType((found, min) -> new LiteralMessage("Integer must not be less than " + min + ", found " + found)); private static final Dynamic2CommandExceptionType INTEGER_TOO_SMALL = new Dynamic2CommandExceptionType((found, min) -> new LiteralMessage("Integer must not be less than " + min + ", found " + found));
private static final Dynamic2CommandExceptionType INTEGER_TOO_BIG = new Dynamic2CommandExceptionType((found, max) -> new LiteralMessage("Integer must not be more than " + max + ", found " + found)); private static final Dynamic2CommandExceptionType INTEGER_TOO_BIG = new Dynamic2CommandExceptionType((found, max) -> new LiteralMessage("Integer must not be more than " + max + ", found " + found));
private static final Dynamic2CommandExceptionType LONG_TOO_SMALL = new Dynamic2CommandExceptionType((found, min) -> new LiteralMessage("Long must not be less than " + min + ", found " + found));
private static final Dynamic2CommandExceptionType LONG_TOO_BIG = new Dynamic2CommandExceptionType((found, max) -> new LiteralMessage("Long must not be more than " + max + ", found " + found));
private static final DynamicCommandExceptionType LITERAL_INCORRECT = new DynamicCommandExceptionType(expected -> new LiteralMessage("Expected literal " + expected)); private static final DynamicCommandExceptionType LITERAL_INCORRECT = new DynamicCommandExceptionType(expected -> new LiteralMessage("Expected literal " + expected));
private static final SimpleCommandExceptionType READER_EXPECTED_START_OF_QUOTE = new SimpleCommandExceptionType(new LiteralMessage("Expected quote to start a string")); private static final SimpleCommandExceptionType READER_EXPECTED_START_OF_QUOTE = new SimpleCommandExceptionType(new LiteralMessage("Expected quote to start a string"));
@ -23,6 +26,8 @@ public class BuiltInExceptions implements BuiltInExceptionProvider {
private static final DynamicCommandExceptionType READER_INVALID_BOOL = new DynamicCommandExceptionType(value -> new LiteralMessage("Invalid bool, expected true or false but found '" + value + "'")); private static final DynamicCommandExceptionType READER_INVALID_BOOL = new DynamicCommandExceptionType(value -> new LiteralMessage("Invalid bool, expected true or false but found '" + value + "'"));
private static final DynamicCommandExceptionType READER_INVALID_INT = new DynamicCommandExceptionType(value -> new LiteralMessage("Invalid integer '" + value + "'")); private static final DynamicCommandExceptionType READER_INVALID_INT = new DynamicCommandExceptionType(value -> new LiteralMessage("Invalid integer '" + value + "'"));
private static final SimpleCommandExceptionType READER_EXPECTED_INT = new SimpleCommandExceptionType(new LiteralMessage("Expected integer")); private static final SimpleCommandExceptionType READER_EXPECTED_INT = new SimpleCommandExceptionType(new LiteralMessage("Expected integer"));
private static final DynamicCommandExceptionType READER_INVALID_LONG = new DynamicCommandExceptionType(value -> new LiteralMessage("Invalid long '" + value + "'"));
private static final SimpleCommandExceptionType READER_EXPECTED_LONG = new SimpleCommandExceptionType((new LiteralMessage("Expected long")));
private static final DynamicCommandExceptionType READER_INVALID_DOUBLE = new DynamicCommandExceptionType(value -> new LiteralMessage("Invalid double '" + value + "'")); private static final DynamicCommandExceptionType READER_INVALID_DOUBLE = new DynamicCommandExceptionType(value -> new LiteralMessage("Invalid double '" + value + "'"));
private static final SimpleCommandExceptionType READER_EXPECTED_DOUBLE = new SimpleCommandExceptionType(new LiteralMessage("Expected double")); private static final SimpleCommandExceptionType READER_EXPECTED_DOUBLE = new SimpleCommandExceptionType(new LiteralMessage("Expected double"));
private static final DynamicCommandExceptionType READER_INVALID_FLOAT = new DynamicCommandExceptionType(value -> new LiteralMessage("Invalid float '" + value + "'")); private static final DynamicCommandExceptionType READER_INVALID_FLOAT = new DynamicCommandExceptionType(value -> new LiteralMessage("Invalid float '" + value + "'"));
@ -65,6 +70,16 @@ public class BuiltInExceptions implements BuiltInExceptionProvider {
return INTEGER_TOO_BIG; return INTEGER_TOO_BIG;
} }
@Override
public Dynamic2CommandExceptionType longTooLow() {
return LONG_TOO_SMALL;
}
@Override
public Dynamic2CommandExceptionType longTooHigh() {
return LONG_TOO_BIG;
}
@Override @Override
public DynamicCommandExceptionType literalIncorrect() { public DynamicCommandExceptionType literalIncorrect() {
return LITERAL_INCORRECT; return LITERAL_INCORRECT;
@ -100,6 +115,16 @@ public class BuiltInExceptions implements BuiltInExceptionProvider {
return READER_EXPECTED_INT; return READER_EXPECTED_INT;
} }
@Override
public DynamicCommandExceptionType readerInvalidLong() {
return READER_INVALID_LONG;
}
@Override
public SimpleCommandExceptionType readerExpectedLong() {
return READER_EXPECTED_LONG;
}
@Override @Override
public DynamicCommandExceptionType readerInvalidDouble() { public DynamicCommandExceptionType readerInvalidDouble() {
return READER_INVALID_DOUBLE; return READER_INVALID_DOUBLE;

View file

@ -0,0 +1,81 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
package com.mojang.brigadier.arguments;
import com.google.common.testing.EqualsTester;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.context.CommandContextBuilder;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import static com.mojang.brigadier.arguments.LongArgumentType.longArg;
import static org.hamcrest.Matchers.hasToString;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
@RunWith(MockitoJUnitRunner.class)
public class LongArgumentTypeTest {
private LongArgumentType type;
@Mock
private CommandContextBuilder<Object> context;
@Before
public void setUp() throws Exception {
type = longArg(-100, 1_000_000_000_000L);
}
@Test
public void parse() throws Exception {
final StringReader reader = new StringReader("15");
assertThat(longArg().parse(reader), is(15L));
assertThat(reader.canRead(), is(false));
}
@Test
public void parse_tooSmall() throws Exception {
final StringReader reader = new StringReader("-5");
try {
longArg(0, 100).parse(reader);
fail();
} catch (final CommandSyntaxException ex) {
assertThat(ex.getType(), is(CommandSyntaxException.BUILT_IN_EXCEPTIONS.longTooLow()));
assertThat(ex.getCursor(), is(0));
}
}
@Test
public void parse_tooBig() throws Exception {
final StringReader reader = new StringReader("5");
try {
longArg(-100, 0).parse(reader);
fail();
} catch (final CommandSyntaxException ex) {
assertThat(ex.getType(), is(CommandSyntaxException.BUILT_IN_EXCEPTIONS.longTooHigh()));
assertThat(ex.getCursor(), is(0));
}
}
@Test
public void testEquals() throws Exception {
new EqualsTester()
.addEqualityGroup(longArg(), longArg())
.addEqualityGroup(longArg(-100, 100), longArg(-100, 100))
.addEqualityGroup(longArg(-100, 50), longArg(-100, 50))
.addEqualityGroup(longArg(-50, 100), longArg(-50, 100))
.testEquals();
}
@Test
public void testToString() throws Exception {
assertThat(longArg(), hasToString("longArg()"));
assertThat(longArg(-100), hasToString("longArg(-100)"));
assertThat(longArg(-100, 100), hasToString("longArg(-100, 100)"));
assertThat(longArg(Long.MIN_VALUE, 100), hasToString("longArg(-9223372036854775808, 100)"));
}
}