diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/argTests.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/argTests.kt new file mode 100644 index 0000000..96dad21 --- /dev/null +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/argTests.kt @@ -0,0 +1,80 @@ +package com.mattmx.ktgui.commands.declarative.arg + +import com.mattmx.ktgui.commands.declarative.arg.impl.* +import kotlin.math.min + +class ArgumentProcessor( + val args: List +) { + var pointer = 0 + val values = hashMapOf() + + // Should be in the [DeclarativeCommandBuilder] + val permittedFlags = arrayListOf() + val options = OptionSyntax() + + fun peek(i: Int) = args.getOrNull(pointer + i) + fun current() = peek(0) + fun next(): String? { + // Check if it is a flag + pointer++ + while (current().let { it != null && options.match(it) }) { + val optionOrPointerId = options.removePrefixFrom(current()!!) + + // TODO check if expected id is expected and if it is a flag or option + if (permittedFlags.any { it.chatName() == optionOrPointerId }) { + values[optionOrPointerId] = true.toString() + } else { + // TODO this should read the argument type args (does that make sense?) + // e.g '--test "hello world"' -> hello world + val value = peek(1) ?: continue + values[optionOrPointerId] = value + pointer++ + } + + pointer++ + } + + return current() + } + + fun takeOne(argId: String) { + values[argId] = next() ?: return + } + + fun takeUntilNot(argId: String, block: String.() -> Boolean) { + var current = next() + val list = arrayListOf() + + if (current != null) { + list.add(current) + } + + while (current != null && block(current)) { + current = next() + if (current != null) { + list.add(current) + } + } + values[argId] = list.joinToString(" ") + } + + fun takeRemaining(argId: String) { + takeUntilNot(argId) { pointer < args.size } + } +} + +fun main() { + val ping by flag() + val option by optionArgument() + + val args = "msg MattMX foo bar --ping --option 'hello world'".split(" ") + val processor = ArgumentProcessor(args) + + processor.permittedFlags.add(ping) + + processor.takeOne("username") + processor.takeRemaining("msg") + + println(processor.values) +} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/FlagArgument.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/FlagArgument.kt new file mode 100644 index 0000000..138d6f5 --- /dev/null +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/FlagArgument.kt @@ -0,0 +1,12 @@ +package com.mattmx.ktgui.commands.declarative.arg.impl + +import com.mattmx.ktgui.commands.declarative.arg.Argument +import com.mattmx.ktgui.commands.declarative.arg.consumer.SingleArgumentConsumer + +class FlagArgument( + name: String +) : Argument(name, "boolean", SingleArgumentConsumer()) { + + fun chatName() = name().replace("_", "-") + +} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/OptionArgument.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/OptionArgument.kt new file mode 100644 index 0000000..d360b79 --- /dev/null +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/OptionArgument.kt @@ -0,0 +1,11 @@ +package com.mattmx.ktgui.commands.declarative.arg.impl + +import com.mattmx.ktgui.commands.declarative.arg.Argument +import com.mattmx.ktgui.commands.declarative.arg.consumer.ArgumentConsumer + +class OptionArgument( + name: String, + typeName: String, + consumer: ArgumentConsumer +) : Argument(name, typeName, consumer) { +} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/OptionSyntax.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/OptionSyntax.kt new file mode 100644 index 0000000..e760899 --- /dev/null +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/OptionSyntax.kt @@ -0,0 +1,11 @@ +package com.mattmx.ktgui.commands.declarative.arg.impl + +data class OptionSyntax( + val prefix: String = "--" +) { + fun regex() = "$prefix.+".toRegex() + + fun match(str: String) = str.matches(regex()) + + fun removePrefixFrom(str: String) = str.replaceFirst(prefix, "") +} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/args.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/args.kt index 2240c3e..f23a708 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/args.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/args.kt @@ -3,6 +3,7 @@ package com.mattmx.ktgui.commands.declarative.arg.impl import com.mattmx.ktgui.commands.declarative.arg.Argument import com.mattmx.ktgui.commands.declarative.arg.consumer.GreedyArgumentConsumer import com.mattmx.ktgui.commands.declarative.arg.consumer.SingleArgumentConsumer +import net.kyori.adventure.bossbar.BossBar.Flag import kotlin.properties.ReadOnlyProperty import kotlin.reflect.KProperty @@ -21,7 +22,13 @@ fun argument(type: String, name: String, isVarArg: Boolean) = Argument(name, type, if (isVarArg) GreedyArgumentConsumer() else SingleArgumentConsumer()) fun stringArgument(type: String = "string", isVarArg: Boolean = false) = - delegateArgument(StringArgument(DELEGATED_ARG_NAME, type, if (isVarArg) GreedyArgumentConsumer() else SingleArgumentConsumer())) + delegateArgument( + StringArgument( + DELEGATED_ARG_NAME, + type, + if (isVarArg) GreedyArgumentConsumer() else SingleArgumentConsumer() + ) + ) fun greedyStringArgument(type: String = "string") = stringArgument(type, true) @@ -45,4 +52,9 @@ fun simpleArgument(type: String = "") = delegateArgument(SimpleArgument(DELEGATED_ARG_NAME, type, SingleArgumentConsumer())) inline fun > enumArgument(type: String = E::class.java.simpleName) = - delegateArgument(EnumArgument(E::class.javaObjectType, DELEGATED_ARG_NAME, type)) \ No newline at end of file + delegateArgument(EnumArgument(E::class.javaObjectType, DELEGATED_ARG_NAME, type)) + +fun flag() = delegateArgument(FlagArgument(DELEGATED_ARG_NAME)) + +inline fun optionArgument(type: String = T::class.java.simpleName) = + delegateArgument(OptionArgument(DELEGATED_ARG_NAME, type, SingleArgumentConsumer())) \ No newline at end of file