improve argument parsing
fail fast by parsing arguments before command execution instead of on demand
This commit is contained in:
@@ -95,9 +95,7 @@ class Command private constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun cli(
|
fun cli(block: Command.Builder.() -> Unit): Command {
|
||||||
block: Command.Builder.() -> Unit,
|
|
||||||
): Command {
|
|
||||||
val builder = Command.Builder(-1, null)
|
val builder = Command.Builder(-1, null)
|
||||||
builder.block()
|
builder.block()
|
||||||
return builder.build()
|
return builder.build()
|
||||||
|
|||||||
@@ -12,11 +12,7 @@ class Execution private constructor(
|
|||||||
val arguments: List<Arg>,
|
val arguments: List<Arg>,
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
fun from(
|
fun from(command: Command, cmd: List<String>, arg: List<String>): Execution {
|
||||||
command: Command,
|
|
||||||
cmd: List<String>,
|
|
||||||
arg: List<String>,
|
|
||||||
): Execution {
|
|
||||||
val commands = Cmd.from(cmd)
|
val commands = Cmd.from(cmd)
|
||||||
val arguments = Arg.from(command, arg)
|
val arguments = Arg.from(command, arg)
|
||||||
return Execution(commands, arguments)
|
return Execution(commands, arguments)
|
||||||
@@ -33,7 +29,7 @@ class Execution private constructor(
|
|||||||
|
|
||||||
class Arg(
|
class Arg(
|
||||||
val name: String,
|
val name: String,
|
||||||
val value: String?,
|
val value: Any,
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
fun from(command: Command, arg: List<String>): List<Arg> = buildList {
|
fun from(command: Command, arg: List<String>): List<Arg> = buildList {
|
||||||
@@ -68,10 +64,10 @@ class Execution private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (name in names) {
|
for (name in names) {
|
||||||
if (command.arguments.none { name in it.names })
|
val argument = command.arguments.firstOrNull { name in it.names }
|
||||||
throw UnknownArgumentException(name)
|
?: throw UnknownArgumentException(name)
|
||||||
|
|
||||||
//TODO parse early
|
val value = argument.parser.parse(value) as Any
|
||||||
add(Arg(name, value))
|
add(Arg(name, value))
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
@@ -88,26 +84,11 @@ class Execution private constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun Command.Key.getValue(
|
operator fun Command.Key.getValue(thisRef: Any?, property: KProperty<*>): String = commands[index].name
|
||||||
thisRef: Any?,
|
|
||||||
property: KProperty<*>,
|
|
||||||
): String = commands[index].name
|
|
||||||
|
|
||||||
operator fun <T> Argument.Single<T>.getValue(
|
@Suppress("UNCHECKED_CAST")
|
||||||
thisRef: Any?,
|
private fun <T> Argument<T>.getValue(): T? = arguments.firstOrNull { it.name in names }?.value as? T
|
||||||
property: KProperty<*>,
|
operator fun <T> Argument.Single<T>.getValue(thisRef: Any?, property: KProperty<*>): T = getValue()!!
|
||||||
): T = arguments.single { it.name in names }
|
operator fun <T> Argument.SingleOrElse<T>.getValue(thisRef: Any?, property: KProperty<*>): T = getValue() ?: other
|
||||||
.let { parser.parse(it.value) }
|
operator fun <T> Argument.SingleOrNull<T>.getValue(thisRef: Any?, property: KProperty<*>): T? = getValue()
|
||||||
|
|
||||||
operator fun <T> Argument.SingleOrElse<T>.getValue(
|
|
||||||
thisRef: Any?,
|
|
||||||
property: KProperty<*>,
|
|
||||||
): T = arguments.singleOrNull { it.name in names }
|
|
||||||
?.let { parser.parse(it.value) } ?: other
|
|
||||||
|
|
||||||
operator fun <T> Argument.SingleOrNull<T>.getValue(
|
|
||||||
thisRef: Any?,
|
|
||||||
property: KProperty<*>,
|
|
||||||
): T? = arguments.singleOrNull { it.name in names }
|
|
||||||
?.let { parser.parse(it.value) }
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user