-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #189 from RedstoneTools/dev
Merge dev
- Loading branch information
Showing
10 changed files
with
298 additions
and
47 deletions.
There are no files selected for viewing
33 changes: 33 additions & 0 deletions
33
...ava/tools/redstone/redstonetools/features/arguments/serializers/BigIntegerSerializer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package tools.redstone.redstonetools.features.arguments.serializers; | ||
|
||
import java.math.BigInteger; | ||
import java.util.Optional; | ||
|
||
public class BigIntegerSerializer extends IntLikeSerializer<BigInteger> { | ||
private static final BigIntegerSerializer INSTANCE = new BigIntegerSerializer(null, null); | ||
|
||
public static BigIntegerSerializer bigInteger() { | ||
return INSTANCE; | ||
} | ||
|
||
public static BigIntegerSerializer bigInteger(BigInteger min) { | ||
return new BigIntegerSerializer(min, null); | ||
} | ||
|
||
public static BigIntegerSerializer bigInteger(BigInteger min, BigInteger max) { | ||
return new BigIntegerSerializer(min, max); | ||
} | ||
|
||
private BigIntegerSerializer(BigInteger min, BigInteger max) { | ||
super(BigInteger.class, min, max); | ||
} | ||
|
||
@Override | ||
protected Optional<BigInteger> tryParseOptional(String string, int radix) { | ||
try { | ||
return Optional.of(new BigInteger(string, radix)); | ||
} catch (NumberFormatException ignored) { | ||
return Optional.empty(); | ||
} | ||
} | ||
} |
115 changes: 115 additions & 0 deletions
115
...n/java/tools/redstone/redstonetools/features/arguments/serializers/IntLikeSerializer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package tools.redstone.redstonetools.features.arguments.serializers; | ||
|
||
import com.mojang.brigadier.StringReader; | ||
import com.mojang.brigadier.context.CommandContext; | ||
import com.mojang.brigadier.exceptions.CommandSyntaxException; | ||
import com.mojang.brigadier.suggestion.Suggestions; | ||
import com.mojang.brigadier.suggestion.SuggestionsBuilder; | ||
import net.minecraft.text.Text; | ||
import tools.redstone.redstonetools.utils.NumberBase; | ||
|
||
import java.util.Collection; | ||
import java.util.Collections; | ||
import java.util.Optional; | ||
import java.util.concurrent.CompletableFuture; | ||
|
||
public abstract class IntLikeSerializer<T extends Comparable<T>> extends TypeSerializer<T, String> { | ||
private final T min; | ||
private final boolean hasMin; | ||
private final T max; | ||
private final boolean hasMax; | ||
|
||
protected IntLikeSerializer(Class<T> clazz, T min, T max) { | ||
super(clazz); | ||
|
||
this.min = min; | ||
hasMin = min != null; | ||
this.max = max; | ||
hasMax = max != null; | ||
} | ||
|
||
@Override | ||
public T deserialize(StringReader reader) throws CommandSyntaxException { | ||
var input = reader.readUnquotedString(); | ||
|
||
try { | ||
return deserialize(input); | ||
} catch (IllegalArgumentException e) { | ||
throw new CommandSyntaxException(null, Text.of(e.getMessage())); | ||
} | ||
} | ||
|
||
@Override | ||
public T deserialize(String serialized) { | ||
var value = deserializeUnchecked(serialized); | ||
|
||
if (hasMin && value.compareTo(min) < 0) { | ||
throw new IllegalArgumentException(value + " is below the minimum of " + min + "."); | ||
} else if (hasMax && value.compareTo(max) > 0) { | ||
throw new IllegalArgumentException(value + " is above the maximum of " + max + "."); | ||
} | ||
|
||
return value; | ||
} | ||
|
||
private T deserializeUnchecked(String serialized) { | ||
if (serialized.length() == 1) { | ||
return tryParse(serialized); | ||
} | ||
|
||
if (serialized.charAt(0) == '0') { | ||
var prefixedBase = serialized.substring(0, 2); | ||
var number = serialized.substring(2); | ||
|
||
// TODO(Refactor): Write a NumberBase.fromCharacter method instead of this that iterates of the NumberBases (add the char to the NumberBase constructor) | ||
var numberBase = switch (prefixedBase.charAt(1)) { | ||
case 'b' -> NumberBase.BINARY; | ||
case 'o' -> NumberBase.OCTAL; | ||
case 'd' -> NumberBase.DECIMAL; | ||
case 'x' -> NumberBase.HEXADECIMAL; | ||
default -> throw new IllegalArgumentException("Invalid base '" + prefixedBase.charAt(1) + "'."); | ||
}; | ||
|
||
return tryParse(number, numberBase.toInt()); | ||
} | ||
|
||
// TODO(Error handling): Add some checks here to make sure the specified base is valid | ||
var parts = serialized.split("_", 2); | ||
if (parts.length == 2) { | ||
var number = parts[0]; | ||
var base = Integer.parseInt(parts[1]); | ||
|
||
return tryParse(number, base); | ||
} | ||
|
||
return tryParse(serialized); | ||
} | ||
|
||
private T tryParse(String string) { | ||
return tryParse(string, 10); | ||
} | ||
|
||
private T tryParse(String string, int radix) { | ||
return tryParseOptional(string, radix) | ||
.orElseThrow(() -> new IllegalArgumentException(radix == 10 | ||
? "Invalid number '" + string + "'." | ||
: "Invalid base " + radix + " number '" + string + "'.")); | ||
} | ||
|
||
protected abstract Optional<T> tryParseOptional(String string, int radix); | ||
|
||
@Override | ||
public String serialize(T value) { | ||
return String.valueOf(value); | ||
} | ||
|
||
@Override | ||
public Collection<String> getExamples() { | ||
return Collections.emptyList(); | ||
} | ||
|
||
@Override | ||
public <R> CompletableFuture<Suggestions> listSuggestions(CommandContext<R> context, SuggestionsBuilder builder) { | ||
return builder.buildFuture(); | ||
} | ||
} |
25 changes: 13 additions & 12 deletions
25
...n/java/tools/redstone/redstonetools/features/arguments/serializers/IntegerSerializer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,32 @@ | ||
package tools.redstone.redstonetools.features.arguments.serializers; | ||
|
||
import com.mojang.brigadier.arguments.ArgumentType; | ||
import com.mojang.brigadier.arguments.IntegerArgumentType; | ||
import java.util.Optional; | ||
|
||
public class IntegerSerializer extends StringBrigadierSerializer<Integer> { | ||
|
||
private static final IntegerSerializer INSTANCE = new IntegerSerializer(IntegerArgumentType.integer()); | ||
public class IntegerSerializer extends IntLikeSerializer<Integer> { | ||
private static final IntegerSerializer INSTANCE = new IntegerSerializer(Integer.MIN_VALUE, Integer.MAX_VALUE); | ||
|
||
public static IntegerSerializer integer() { | ||
return INSTANCE; | ||
} | ||
|
||
public static IntegerSerializer integer(int min) { | ||
return new IntegerSerializer(IntegerArgumentType.integer(min)); | ||
return new IntegerSerializer(min, Integer.MAX_VALUE); | ||
} | ||
|
||
public static IntegerSerializer integer(int min, int max) { | ||
return new IntegerSerializer(IntegerArgumentType.integer(min, max)); | ||
return new IntegerSerializer(min, max); | ||
} | ||
|
||
private IntegerSerializer(ArgumentType<Integer> argumentType) { | ||
super(Integer.class, argumentType); | ||
private IntegerSerializer(int min, int max) { | ||
super(Integer.class, min, max); | ||
} | ||
|
||
@Override | ||
public String serialize(Integer value) { | ||
return String.valueOf(value); | ||
protected Optional<Integer> tryParseOptional(String string, int radix) { | ||
try { | ||
return Optional.of(Integer.parseInt(string, radix)); | ||
} catch (NumberFormatException ignored) { | ||
return Optional.empty(); | ||
} | ||
} | ||
|
||
} |
25 changes: 13 additions & 12 deletions
25
...main/java/tools/redstone/redstonetools/features/arguments/serializers/LongSerializer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,32 @@ | ||
package tools.redstone.redstonetools.features.arguments.serializers; | ||
|
||
import com.mojang.brigadier.arguments.ArgumentType; | ||
import com.mojang.brigadier.arguments.LongArgumentType; | ||
import java.util.Optional; | ||
|
||
public class LongSerializer extends StringBrigadierSerializer<Long> { | ||
|
||
private static final LongSerializer INSTANCE = new LongSerializer(LongArgumentType.longArg()); | ||
public class LongSerializer extends IntLikeSerializer<Long> { | ||
private static final LongSerializer INSTANCE = new LongSerializer(Long.MIN_VALUE, Long.MAX_VALUE); | ||
|
||
public static LongSerializer longArg() { | ||
return INSTANCE; | ||
} | ||
|
||
public static LongSerializer longArg(long min) { | ||
return new LongSerializer(LongArgumentType.longArg(min)); | ||
return new LongSerializer(min, Long.MAX_VALUE); | ||
} | ||
|
||
public static LongSerializer longArg(long min, long max) { | ||
return new LongSerializer(LongArgumentType.longArg(min, max)); | ||
return new LongSerializer(min, max); | ||
} | ||
|
||
private LongSerializer(ArgumentType<Long> argumentType) { | ||
super(Long.class, argumentType); | ||
private LongSerializer(long min, long max) { | ||
super(Long.class, min, max); | ||
} | ||
|
||
@Override | ||
public String serialize(Long value) { | ||
return String.valueOf(value); | ||
protected Optional<Long> tryParseOptional(String string, int radix) { | ||
try { | ||
return Optional.of(Long.parseLong(string, radix)); | ||
} catch (NumberFormatException ignored) { | ||
return Optional.empty(); | ||
} | ||
} | ||
|
||
} |
75 changes: 75 additions & 0 deletions
75
...ava/tools/redstone/redstonetools/features/arguments/serializers/NumberBaseSerializer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package tools.redstone.redstonetools.features.arguments.serializers; | ||
|
||
import com.mojang.brigadier.StringReader; | ||
import com.mojang.brigadier.context.CommandContext; | ||
import com.mojang.brigadier.exceptions.CommandSyntaxException; | ||
import com.mojang.brigadier.suggestion.Suggestions; | ||
import com.mojang.brigadier.suggestion.SuggestionsBuilder; | ||
import net.minecraft.text.Text; | ||
import tools.redstone.redstonetools.utils.NumberBase; | ||
|
||
import java.util.Arrays; | ||
import java.util.Collection; | ||
import java.util.concurrent.CompletableFuture; | ||
|
||
public class NumberBaseSerializer extends TypeSerializer<Integer, String> { | ||
private static final IntegerSerializer INT_SERIALIZER = IntegerSerializer.integer(2, 36); | ||
private static final NumberBaseSerializer INSTANCE = new NumberBaseSerializer(); | ||
|
||
public static NumberBaseSerializer numberBase() { | ||
return INSTANCE; | ||
} | ||
|
||
protected NumberBaseSerializer() { | ||
super(Integer.class); | ||
} | ||
|
||
@Override | ||
public Integer deserialize(StringReader reader) throws CommandSyntaxException { | ||
var input = reader.readUnquotedString(); | ||
|
||
try { | ||
return deserialize(input); | ||
} catch (IllegalArgumentException e) { | ||
throw new CommandSyntaxException(null, Text.of(e.getMessage())); | ||
} | ||
} | ||
|
||
@Override | ||
public Integer deserialize(String serialized) { | ||
try { | ||
return NumberBase.fromString(serialized) | ||
.map(NumberBase::toInt) | ||
.orElseGet(() -> INT_SERIALIZER.deserialize(serialized)); | ||
} catch (IllegalArgumentException e) { | ||
throw new IllegalArgumentException("Invalid base '" + serialized + "'.", e); | ||
} | ||
} | ||
|
||
@Override | ||
public String serialize(Integer value) { | ||
return NumberBase.fromInt(value) | ||
.map(NumberBase::toString) | ||
.orElseGet(() -> INT_SERIALIZER.serialize(value)); | ||
} | ||
|
||
public String serialize(NumberBase value) { | ||
return serialize(value.toInt()); | ||
} | ||
|
||
@Override | ||
public Collection<String> getExamples() { | ||
return Arrays.stream(NumberBase.values()) | ||
.map(this::serialize) | ||
.toList(); | ||
} | ||
|
||
@Override | ||
public <R> CompletableFuture<Suggestions> listSuggestions(CommandContext<R> context, SuggestionsBuilder builder) { | ||
for (var value : NumberBase.values()) { | ||
builder = builder.suggest(serialize(value)); | ||
} | ||
|
||
return builder.buildFuture(); | ||
} | ||
} |
28 changes: 9 additions & 19 deletions
28
src/main/java/tools/redstone/redstonetools/features/commands/BaseConvertFeature.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,28 @@ | ||
package tools.redstone.redstonetools.features.commands; | ||
|
||
import net.minecraft.server.command.ServerCommandSource; | ||
import tools.redstone.redstonetools.features.Feature; | ||
import tools.redstone.redstonetools.features.arguments.Argument; | ||
import tools.redstone.redstonetools.features.feedback.Feedback; | ||
import net.minecraft.server.command.ServerCommandSource; | ||
|
||
import static tools.redstone.redstonetools.features.arguments.serializers.IntegerSerializer.integer; | ||
import static tools.redstone.redstonetools.features.arguments.serializers.StringSerializer.word; | ||
|
||
|
||
import java.math.BigInteger; | ||
|
||
import static tools.redstone.redstonetools.features.arguments.serializers.BigIntegerSerializer.bigInteger; | ||
import static tools.redstone.redstonetools.features.arguments.serializers.NumberBaseSerializer.numberBase; | ||
|
||
@Feature(name = "Base Convert", description = "Converts a number from one base to another.", command = "base") | ||
public class BaseConvertFeature extends CommandFeature { | ||
|
||
public static final Argument<String> number = Argument | ||
.ofType(word()); | ||
public static final Argument<Integer> fromBase = Argument | ||
.ofType(integer(2, 36)); | ||
public static final Argument<BigInteger> number = Argument | ||
.ofType(bigInteger()); | ||
public static final Argument<Integer> toBase = Argument | ||
.ofType(integer(2, 36)); | ||
|
||
.ofType(numberBase()) | ||
.withDefault(10); | ||
|
||
@Override | ||
protected Feedback execute(ServerCommandSource source) { | ||
BigInteger input; | ||
try { | ||
input = new BigInteger(number.getValue(), fromBase.getValue()); | ||
} catch (NumberFormatException e) { | ||
return Feedback.invalidUsage("Inputted number does not match the specified base"); | ||
} | ||
var output = number.getValue().toString(toBase.getValue()); | ||
|
||
var output = input.toString(toBase.getValue()); | ||
return Feedback.success(output); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.