All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.com.github.ajalt.clikt.parameters.options.Convert.kt Maven / Gradle / Ivy

@file:JvmMultifileClass
@file:JvmName("OptionWithValuesKt")

package com.github.ajalt.clikt.parameters.options

import com.github.ajalt.clikt.completion.CompletionCandidates
import com.github.ajalt.clikt.core.BadParameterValue
import com.github.ajalt.clikt.core.UsageError
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName


/**
 * Convert the option's value type.
 *
 * The [conversion] is called once for each value in each invocation of the option. If any errors are thrown,
 * they are caught and a [BadParameterValue] is thrown with the error message. You can call `fail` to throw a
 * [BadParameterValue] manually.
 *
 * You can call `convert` more than once to wrap the result of the previous `convert`, but it cannot
 * be called after [transformAll] (e.g. [multiple]) or [transformValues] (e.g. [pair]).
 *
 * ## Example
 *
 * ```
 * val bd: BigDecimal? by option().convert { it.toBigDecimal() }
 * val fileText: ByteArray? by option().file().convert { it.readBytes() }
 * ```
 *
 * @param metavar The metavar for the type. Overridden by a metavar passed to [option].
 * @param envvarSplit If the value is read from an envvar, the pattern to split the value on. The default
 *   splits on whitespace. This value is can be overridden by passing a value to the [option] function.
 * @param completionCandidates candidates to use when completing this option in shell autocomplete,
 *   if no candidates are specified in [option]
 */
inline fun  NullableOption.convert(
        metavar: String = "VALUE",
        envvarSplit: Regex = this.envvarSplit.default,
        completionCandidates: CompletionCandidates = completionCandidatesWithDefault.default,
        crossinline conversion: ValueConverter
): NullableOption {
    val proc: ValueTransformer = {
        try {
            conversion(transformValue(it))
        } catch (err: UsageError) {
            err.paramName = name
            throw err
        } catch (err: Exception) {
            fail(err.message ?: "")
        }
    }
    return copy(proc, defaultEachProcessor(), defaultAllProcessor(), defaultValidator(),
            metavarWithDefault = metavarWithDefault.copy(default = metavar),
            envvarSplit = this.envvarSplit.copy(default = envvarSplit),
            completionCandidatesWithDefault = completionCandidatesWithDefault.copy(default = completionCandidates)
    )
}


/**
 * Change to option to take any number of values, separated by a [regex].
 *
 * This must be called after converting the value type, and before other transforms.
 *
 * ### Example:
 *
 * ```
 * val opt: List? by option().int().split(Regex(","))
 * ```
 *
 * Which can be called like this:
 *
 * `./program --opt 1,2,3`
 */
fun  NullableOption.split(regex: Regex)
        : OptionWithValues?, List, ValueT> {
    return copy(
            transformValue = transformValue,
            transformEach = { it },
            transformAll = defaultAllProcessor(),
            validator = defaultValidator(),
            nvalues = 1,
            valueSplit = regex
    )
}

/**
 * Change to option to take any number of values, separated by a string [delimiter].
 *
 * This must be called after converting the value type, and before other transforms.
 *
 * ### Example:
 *
 * ```
 * val opt: List? by option().int().split(",")
 * ```
 *
 * Which can be called like this:
 *
 * `./program --opt 1,2,3`
 */
fun  NullableOption.split(delimiter: String)
        : OptionWithValues?, List, ValueT> {
    return split(Regex.fromLiteral(delimiter))
}


/**
 * Split this option's value into two with a [delimiter].
 *
 * If the delimiter is not present in the value, the [second][Pair.second] part of the pair will be
 * an empty string. You can use [validate] to reject these values.
 *
 * You cannot call [convert] before this function, but you can call it after.
 *
 * ### Example:
 *
 * ```
 * val opt: option("-o").splitPair()
 * ```
 *
 * Which can be called like this:
 *
 * `./program -o key=value`
 */
fun RawOption.splitPair(delimiter: String = "="): NullableOption, Pair> {
    return convert { it.substringBefore(delimiter) to it.substringAfter(delimiter, missingDelimiterValue = "") }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy