Skip to content

Commit

Permalink
impl new ArgumentProcessor to process arguments correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt-MX committed Jun 13, 2024
1 parent 4ddce3d commit 678c2ff
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -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<String>
) {
var pointer = 0
val values = hashMapOf<String, String>()

// Should be in the [DeclarativeCommandBuilder]
val permittedFlags = arrayListOf<FlagArgument>()
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<String>()

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<String>()

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)
}
Original file line number Diff line number Diff line change
@@ -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<String>(name, "boolean", SingleArgumentConsumer()) {

fun chatName() = name().replace("_", "-")

}
Original file line number Diff line number Diff line change
@@ -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<T : Any>(
name: String,
typeName: String,
consumer: ArgumentConsumer
) : Argument<T>(name, typeName, consumer) {
}
Original file line number Diff line number Diff line change
@@ -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, "")
}
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -21,7 +22,13 @@ fun <T : Any> argument(type: String, name: String, isVarArg: Boolean) =
Argument<T>(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)
Expand All @@ -45,4 +52,9 @@ fun <T : Any> simpleArgument(type: String = "") =
delegateArgument(SimpleArgument<T>(DELEGATED_ARG_NAME, type, SingleArgumentConsumer()))

inline fun <reified E : Enum<E>> enumArgument(type: String = E::class.java.simpleName) =
delegateArgument(EnumArgument(E::class.javaObjectType, DELEGATED_ARG_NAME, type))
delegateArgument(EnumArgument(E::class.javaObjectType, DELEGATED_ARG_NAME, type))

fun flag() = delegateArgument(FlagArgument(DELEGATED_ARG_NAME))

inline fun <reified T : Any> optionArgument(type: String = T::class.java.simpleName) =
delegateArgument(OptionArgument<T>(DELEGATED_ARG_NAME, type, SingleArgumentConsumer()))

0 comments on commit 678c2ff

Please sign in to comment.