Updates argument parser to be more complete

This commit is contained in:
zontreck 2023-12-05 11:31:58 -07:00
parent 42795e0841
commit 87287179c6
12 changed files with 319 additions and 41 deletions

4
.gitignore vendored
View file

@ -1,9 +1,11 @@
# Ignore Gradle project-specific cache directory # Ignore Gradle project-specific cache directory
.gradle .gradle
.idea
# Ignore Gradle build output directory # Ignore Gradle build output directory
build build
bin bin
# Visual Studio Code # Visual Studio Code
.vscode .vscode
*.class

View file

@ -55,8 +55,12 @@ repositories {
dependencies { dependencies {
implementation "dev.zontreck:EventsBus:${Bus_API}.${Bus_Patch}" implementation "dev.zontreck:EventsBus:${Bus_API}.${Bus_Patch}"
api "dev.zontreck:EventsBus:${Bus_API}.${Bus_Patch}:sources" api "dev.zontreck:EventsBus:${Bus_API}.${Bus_Patch}:sources"
testImplementation platform('org.junit:junit-bom:5.9.1')
testImplementation 'org.junit.jupiter:junit-jupiter'
} }
def MAVEN_PASSWORD_PROPERTY = "AriasCreationsMavenPassword" def MAVEN_PASSWORD_PROPERTY = "AriasCreationsMavenPassword"
@ -82,3 +86,7 @@ publishing {
} }
} }
} }
test {
useJUnitPlatform()
}

View file

@ -1,10 +1,9 @@
package dev.zontreck.ariaslib.args; package dev.zontreck.ariaslib.args;
public class Argument { public abstract class Argument<T> {
public boolean isSet = false;
public boolean hasValue = false; public boolean hasValue = false;
public String name; public String name;
private String value;
/** /**
* Initializes a boolean only command line toggle * Initializes a boolean only command line toggle
@ -12,24 +11,24 @@ public class Argument {
* @param name The option name * @param name The option name
*/ */
public Argument(String name) { public Argument(String name) {
this(name, ""); this.name = name;
} }
/** /**
* Initializes the argument with a value * Retrieves the current argument's type
* *
* @param name The name of the command line option * @return The argument type!
* @param value The value
*/ */
public Argument(String name, String value) { public abstract ArgumentType getType();
if (value != "") hasValue = true;
isSet = true;
this.name = name;
this.value = value;
}
public String getValue() { /**
if (hasValue) return value; * Retrieves the value.
else throw new IllegalArgumentException("No value"); *
* @return The value
* @throws IllegalArgumentException When there is no value
*/
public T getValue() throws IllegalArgumentException {
throw new IllegalArgumentException("No value");
} }
} }

View file

@ -0,0 +1,25 @@
package dev.zontreck.ariaslib.args;
public enum ArgumentType {
/**
* This indicates a string. It may possibly have a default value
*/
STRING,
/**
* This indicates a boolean
* <p>
* This may have a default value, which initiates a BooleanArgument
*/
BOOLEAN,
/**
* This indicates a data type of integer
* The type of integer arg is determined by the length of the integer.
*/
INTEGER,
/**
* This is a long value, which can hold larger values than a integer. The type of integer arg is determined by the length of the integer.
*/
LONG
}

View file

@ -10,21 +10,38 @@ public class Arguments {
args.put(arg.name, arg); args.put(arg.name, arg);
} }
public String getArg(String argumentName, String defaultValue) { /**
if (!args.containsKey(argumentName)) { * Checks for and returns the argument
return defaultValue; *
} * @param argName The argument's name
* @return The argument instance, or null if not found
Argument arg = args.get(argumentName); */
if (arg.hasValue) { public Argument getArg(String argName) {
return arg.getValue(); if (hasArg(argName))
} else { return args.get(argName);
return defaultValue; else return null;
}
} }
/**
* Checks if the argument is set.
*
* @param argName The argument's name to check for
* @return True if the argument is present. This does not indicate if the argument has a value
*/
public boolean hasArg(String argName) { public boolean hasArg(String argName) {
return args.containsKey(argName); return args.containsKey(argName);
} }
/**
* Checks the argument (if it exists), for whether a value is set
*
* @param argName This is the argument name
* @return True if a value is set
* @throws IllegalArgumentException If there is no such argument
*/
public boolean argHasValue(String argName) throws IllegalArgumentException {
if (hasArg(argName)) {
return getArg(argName).hasValue;
} else throw new IllegalArgumentException(("No such argument"));
}
} }

View file

@ -0,0 +1,20 @@
package dev.zontreck.ariaslib.args;
public class ArgumentsBuilder {
private Arguments args = new Arguments();
public static ArgumentsBuilder builder() {
return new ArgumentsBuilder();
}
public ArgumentsBuilder withArgument(Argument arg) {
args.setArg(arg);
return this;
}
public Arguments build()
{
return args;
}
}

View file

@ -2,33 +2,96 @@ package dev.zontreck.ariaslib.args;
public class ArgumentsParser { public class ArgumentsParser {
public static Arguments parseArguments(String[] args) { public static Arguments parseArguments(String[] args, Arguments defaults) {
Arguments arguments = new Arguments(); Arguments arguments = new Arguments();
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
Argument arg = parseArgument(args[i]); Argument arg = parseArgument(args[i]);
if (arg != null) { if (arg != null) {
if (arg.hasValue && i + 1 < args.length) { Argument defaultArg = null;
arguments.setArg(arg); if (defaults.hasArg(arg.name)) {
i++; // Skip next value as it's the argument's value defaultArg = defaults.getArg(arg.name);
} else {
arguments.setArg(arg); // Argument without value, default to empty string
} }
if (i + 1 < args.length) {
i++;
}
if (!arg.hasValue) {
if (defaultArg != null) {
arg = defaultArg;
}
}
arguments.setArg(arg);
} }
} }
return arguments; return arguments;
} }
/**
* Parses and returns an argument with a type set
* @param arg The argument to parse with double tack
* @return Typed Argument
* @throws IllegalArgumentException when no type matches and the input is malformed in some way
*/
public static Argument parseArgument(String arg) { public static Argument parseArgument(String arg) {
if (arg.startsWith("--")) { if (arg.startsWith("--")) {
String[] parts = arg.split("=", 1); String[] parts = arg.split("=");
String name = getNamePart(parts[0]);
if (parts.length == 1) { if (parts.length == 1) {
return new Argument(parts[0].substring(2)); return new BooleanArgument(name);
} else {
return new Argument(parts[0].substring(2), parts[1]); } else if (parts.length == 2) {
} String value = getValuePart(parts[1]);
ArgumentType typeOfArg = getArgumentType(value);
switch(typeOfArg)
{
case INTEGER:
{
return new IntegerArgument(name, Integer.parseInt(value));
}
case LONG:
{
return new LongArgument(name, Long.parseLong(value));
}
case BOOLEAN:
{
return new BooleanArgument(name);
}
default:
{
return new StringArgument(name, value);
}
}
} else throw new IllegalArgumentException("The argument is malformed. Remember to use --arg=val, or --toggle");
} else { } else {
return null; // Not a valid argument format throw new IllegalArgumentException("Not a valid argument format");
} }
} }
protected static String getNamePart(String entry) {
return entry.substring(2);
}
protected static String getValuePart(String entry) {
return entry;
}
protected static ArgumentType getArgumentType(String input) {
try {
Integer.parseInt(input);
return ArgumentType.INTEGER;
}catch(Exception e){}
try{
Long.parseLong(input);
return ArgumentType.LONG;
}catch(Exception E){
}
if(input.isEmpty())
return ArgumentType.BOOLEAN;
else return ArgumentType.STRING;
}
} }

View file

@ -0,0 +1,27 @@
package dev.zontreck.ariaslib.args;
public class BooleanArgument extends Argument<Boolean> {
private boolean value;
/**
* Initializes a boolean only command line toggle
*
* @param name The option name
*/
public BooleanArgument(String name) {
super(name);
this.hasValue = true;
this.value = value;
}
@Override
public Boolean getValue() {
return value;
}
@Override
public ArgumentType getType() {
return ArgumentType.BOOLEAN;
}
}

View file

@ -0,0 +1,21 @@
package dev.zontreck.ariaslib.args;
public class IntegerArgument extends Argument<Integer> {
private int value;
public IntegerArgument(String name, int value) {
super(name);
this.hasValue = true;
this.value = value;
}
@Override
public ArgumentType getType() {
return ArgumentType.INTEGER;
}
@Override
public Integer getValue() {
return value;
}
}

View file

@ -0,0 +1,21 @@
package dev.zontreck.ariaslib.args;
public class LongArgument extends Argument<Long> {
private long value;
public LongArgument(String name, long value) {
super(name);
this.hasValue = true;
this.value = value;
}
@Override
public ArgumentType getType() {
return ArgumentType.LONG;
}
@Override
public Long getValue() {
return value;
}
}

View file

@ -0,0 +1,22 @@
package dev.zontreck.ariaslib.args;
public class StringArgument extends Argument<String> {
private String value;
public StringArgument(String name, String value) {
super(name);
this.value = value;
this.hasValue = true;
}
@Override
public String getValue() {
return value;
}
@Override
public ArgumentType getType() {
return ArgumentType.STRING;
}
}

View file

@ -0,0 +1,53 @@
package dev.zontreck.ariaslib.args;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.*;
public class ArgumentsParserTest {
@ParameterizedTest
@ValueSource(strings = {"--test", "--arg", "--testing2"})
void testGetNamePart(String entry) {
String arg = ArgumentsParser.getNamePart(entry);
assertFalse(arg.startsWith("--"));
assertFalse(arg.isEmpty());
}
@ParameterizedTest
@CsvSource(value = {"test", "test2", "281", "true"})
void testGetValuePart(String entry) {
assertFalse(entry.isEmpty());
}
@ParameterizedTest
@ValueSource(strings = {"test", "1", "922337203685477580", ""})
void testGetArgumentType(String input)
{
ArgumentType test = ArgumentsParser.getArgumentType(input);
System.out.println("Testing: " + input + "; Type: " + test);
if(input.startsWith("t"))
{
assertTrue(test == ArgumentType.STRING);
}else if(input.startsWith("1"))
{
assertTrue(test == ArgumentType.INTEGER);
} else if(input.startsWith("9"))
{
assertTrue(test == ArgumentType.LONG);
}else assertTrue(test == ArgumentType.BOOLEAN);
}
@ParameterizedTest
@CsvSource(value = {"--test=1", "--enable", "--set=84375488888444", "--file=test.dat"})
void testParseArgument(String arg)
{
Argument args = ArgumentsParser.parseArgument(arg);
assertFalse(args.name.isEmpty());
assertTrue(args.hasValue);
}
}