Kotlin / kotlinx-cli

Pure Kotlin implementation of a generic CLI parser.
Apache License 2.0
913 stars 70 forks source link

Transform the value of an argument #28

Open GitAntoinee opened 4 years ago

GitAntoinee commented 4 years ago

Hello, Is there a way to transform the value of an argument like:

val parser = ArgParser(args)
val file: File by parser.option(ArgType.String, transform = { File(it) })

instead of

val parser = ArgParser(args)
val filename: String by parser.option(ArgType.String)
val file: File = File(filename)
GitAntoinee commented 4 years ago

Or another way with a function:

val parser = ArgParser(args)
val file: File by parser.option(ArgType.String).transform { File(it) }
LepilkinaElena commented 4 years ago

Now you can't do so. And I have doubts that you really need transformation in current example. It seems that you need new ArgType.File (unfortunately it isn't supported yet). Or could you provide another example where you need exactly transformation?

GitAntoinee commented 4 years ago

Hello, thanks for the reply. I do not think ArgType.File is supported because the File class used in the examples above is java.io.File, which is not in Kotlin's standard library.

The transformation can be very useful when you need to create an instance from a primitive (Int, Double, String, etc).

Here is another example:

val parser = ArgParser(args)
val repository: UserRepository by parser.option(ArgType.String, transform = { userId: String -> UserRepository(host) })
LepilkinaElena commented 4 years ago

Ok, I unsertood. That was an idea that user can describe his own custom ArgType

You can implement this now using

data class UserRepository(val value: kotlin.String)
object UserRepositoryArgType : ArgType<UserRepository>(true) {
    override val description: kotlin.String
        get() = "{ UserRepository }"

    // You can add checks in case if not all values are valid.
    override fun convert(value: kotlin.String, name: kotlin.String): UserRepository = UserRepository(value)
}

val parser = ArgParser(args)
val repository by parser.option(UserRepositoryArgType)

Is this enough?

GitAntoinee commented 4 years ago

Hello, I know I can do it in this manner, but I do not want to create a new ArgType for each class. If I am not too bored, I will create a pull request