From 647f859b639e52be5f34aaa3013156e5ba080236 Mon Sep 17 00:00:00 2001 From: Nathan Adams Date: Thu, 16 Nov 2017 14:28:21 +0100 Subject: [PATCH] Added readFloat to StringReader --- .../com/mojang/brigadier/StringReader.java | 21 ++++++- .../arguments/FloatArgumentType.java | 2 +- .../mojang/brigadier/StringReaderTest.java | 62 +++++++++++++++++++ 3 files changed, 83 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/mojang/brigadier/StringReader.java b/src/main/java/com/mojang/brigadier/StringReader.java index abc62cb..b562e1e 100644 --- a/src/main/java/com/mojang/brigadier/StringReader.java +++ b/src/main/java/com/mojang/brigadier/StringReader.java @@ -16,6 +16,8 @@ public class StringReader implements ImmutableStringReader { public static final SimpleCommandExceptionType ERROR_EXPECTED_INT = new SimpleCommandExceptionType("parsing.int.expected", "Expected integer"); public static final ParameterizedCommandExceptionType ERROR_INVALID_DOUBLE = new ParameterizedCommandExceptionType("parsing.double.invalid", "Invalid double '${value}'", "value"); public static final SimpleCommandExceptionType ERROR_EXPECTED_DOUBLE = new SimpleCommandExceptionType("parsing.double.expected", "Expected double"); + public static final ParameterizedCommandExceptionType ERROR_INVALID_FLOAT = new ParameterizedCommandExceptionType("parsing.float.invalid", "Invalid float '${value}'", "value"); + public static final SimpleCommandExceptionType ERROR_EXPECTED_FLOAT = new SimpleCommandExceptionType("parsing.float.expected", "Expected float"); public static final SimpleCommandExceptionType ERROR_EXPECTED_BOOL = new SimpleCommandExceptionType("parsing.bool.expected", "Expected bool"); public static final ParameterizedCommandExceptionType ERROR_EXPECTED_SYMBOL = new ParameterizedCommandExceptionType("parsing.expected", "Expected '${symbol}'", "symbol"); @@ -93,7 +95,7 @@ public class StringReader implements ImmutableStringReader { cursor++; } - private static boolean isAllowedNumber(final char c) { + public static boolean isAllowedNumber(final char c) { return c >= '0' && c <= '9' || c == '.' || c == '-'; } @@ -137,6 +139,23 @@ public class StringReader implements ImmutableStringReader { } } + public float readFloat() throws CommandSyntaxException { + final int start = cursor; + while (canRead() && isAllowedNumber(peek())) { + skip(); + } + final String number = string.substring(start, cursor); + if (number.isEmpty()) { + throw ERROR_EXPECTED_FLOAT.createWithContext(this); + } + try { + return Float.parseFloat(number); + } catch (final NumberFormatException ex) { + cursor = start; + throw ERROR_INVALID_FLOAT.createWithContext(this, number); + } + } + public static boolean isAllowedInUnquotedString(final char c) { return c >= '0' && c <= '9' || c >= 'A' && c <= 'Z' diff --git a/src/main/java/com/mojang/brigadier/arguments/FloatArgumentType.java b/src/main/java/com/mojang/brigadier/arguments/FloatArgumentType.java index f3db966..9f719a9 100644 --- a/src/main/java/com/mojang/brigadier/arguments/FloatArgumentType.java +++ b/src/main/java/com/mojang/brigadier/arguments/FloatArgumentType.java @@ -45,7 +45,7 @@ public class FloatArgumentType implements ArgumentType { @Override public Float parse(final StringReader reader, final CommandContextBuilder contextBuilder) throws CommandSyntaxException { final int start = reader.getCursor(); - final float result = (float) reader.readDouble(); + final float result = reader.readFloat(); if (result < minimum) { reader.setCursor(start); throw ERROR_TOO_SMALL.createWithContext(reader, result, minimum); diff --git a/src/test/java/com/mojang/brigadier/StringReaderTest.java b/src/test/java/com/mojang/brigadier/StringReaderTest.java index 38a2f6f..ce09896 100644 --- a/src/test/java/com/mojang/brigadier/StringReaderTest.java +++ b/src/test/java/com/mojang/brigadier/StringReaderTest.java @@ -361,6 +361,68 @@ public class StringReaderTest { assertThat(reader.getRemaining(), equalTo("foo bar")); } + @Test + public void readFloat() throws Exception { + final StringReader reader = new StringReader("123"); + assertThat(reader.readFloat(), is(123.0f)); + assertThat(reader.getRead(), equalTo("123")); + assertThat(reader.getRemaining(), equalTo("")); + } + + @Test + public void readFloat_withDecimal() throws Exception { + final StringReader reader = new StringReader("12.34"); + assertThat(reader.readFloat(), is(12.34f)); + assertThat(reader.getRead(), equalTo("12.34")); + assertThat(reader.getRemaining(), equalTo("")); + } + + @Test + public void readFloat_negative() throws Exception { + final StringReader reader = new StringReader("-123"); + assertThat(reader.readFloat(), is(-123.0f)); + assertThat(reader.getRead(), equalTo("-123")); + assertThat(reader.getRemaining(), equalTo("")); + } + + @Test + public void readFloat_invalid() throws Exception { + try { + new StringReader("12.34.56").readFloat(); + } catch (final CommandSyntaxException ex) { + assertThat(ex.getType(), is(StringReader.ERROR_INVALID_FLOAT)); + assertThat(ex.getData(), equalTo(ImmutableMap.of("value", "12.34.56"))); + assertThat(ex.getCursor(), is(0)); + } + } + + @Test + public void readFloat_none() throws Exception { + try { + new StringReader("").readFloat(); + } catch (final CommandSyntaxException ex) { + assertThat(ex.getType(), is(StringReader.ERROR_EXPECTED_FLOAT)); + assertThat(ex.getData(), equalTo(Collections.emptyMap())); + assertThat(ex.getCursor(), is(0)); + } + } + + @Test + public void readFloat_withRemaining() throws Exception { + final StringReader reader = new StringReader("12.34 foo bar"); + assertThat(reader.readFloat(), is(12.34f)); + assertThat(reader.getRead(), equalTo("12.34")); + assertThat(reader.getRemaining(), equalTo(" foo bar")); + } + + @Test + public void readFloat_withRemainingImmediate() throws Exception { + final StringReader reader = new StringReader("12.34foo bar"); + assertThat(reader.readFloat(), is(12.34f)); + assertThat(reader.getRead(), equalTo("12.34")); + assertThat(reader.getRemaining(), equalTo("foo bar")); + } + @Test public void expect_correct() throws Exception { final StringReader reader = new StringReader("abc");