feat: Use option name as key for simplicity and consistency

This commit is contained in:
oSumAtrIX 2024-12-24 16:47:48 +01:00
parent fe5fb736cb
commit 754b02e4ca
No known key found for this signature in database
GPG Key ID: A9B3094ACDB604B4
2 changed files with 57 additions and 22 deletions

View File

@ -86,7 +86,7 @@ val disableAdsPatch = bytecodePatch(
execute { execute {
// Fingerprint to find the method to patch. // Fingerprint to find the method to patch.
val showAdsMatch by showAdsFingerprint { val showAdsMatch by showAdsFingerprint {
// More about fingerprints on the next page of the documentation. // More about fingerprints on the next page of the documentation.
} }
// In the method that shows ads, // In the method that shows ads,
@ -122,10 +122,10 @@ To define an option, use the available `option` functions:
```kt ```kt
val patch = bytecodePatch(name = "Patch") { val patch = bytecodePatch(name = "Patch") {
// Add an inbuilt option and delegate it to a property. // Add an inbuilt option and delegate it to a property.
val value by stringOption(key = "option") val value by stringOption(name = "Inbuilt option")
// Add an option with a custom type and delegate it to a property. // Add an option with a custom type and delegate it to a property.
val string by option<String>(key = "string") val string by option<String>(name = "String option")
execute { execute {
println(value) println(value)
@ -139,7 +139,7 @@ Options of a patch can be set after loading the patches with `PatchLoader` by ob
```kt ```kt
loadPatchesJar(patches).apply { loadPatchesJar(patches).apply {
// Type is checked at runtime. // Type is checked at runtime.
first { it.name == "Patch" }.options["option"] = "Value" first { it.name == "Patch" }.options["Option"] = "Value"
} }
``` ```
@ -152,7 +152,7 @@ option.type // The KType of the option. Captures the full type information of th
Options can be declared outside a patch and added to a patch manually: Options can be declared outside a patch and added to a patch manually:
```kt ```kt
val option = stringOption(key = "option") val option = stringOption(name = "Option")
bytecodePatch(name = "Patch") { bytecodePatch(name = "Patch") {
val value by option() val value by option()
@ -249,10 +249,10 @@ The same order is followed for multiple patches depending on the patch.
- A patch can declare compatibility with specific packages and versions, - A patch can declare compatibility with specific packages and versions,
but patches can still be executed on any package or version. but patches can still be executed on any package or version.
It is recommended that compatibility is specified to present known compatible packages and versions. It is recommended that compatibility is specified to present known compatible packages and versions.
- If `compatibleWith` is not used, the patch is treated as compatible with any package - If `compatibleWith` is not used, the patch is treated as compatible with any package
- If a package is specified with no versions, the patch is compatible with any version of the package - If a package is specified with no versions, the patch is compatible with any version of the package
- If an empty array of versions is specified, the patch is not compatible with any version of the package. - If an empty array of versions is specified, the patch is not compatible with any version of the package.
This is useful for declaring incompatibility with a specific package. This is useful for declaring incompatibility with a specific package.
- A patch can raise a `PatchException` at any time of execution to indicate that the patch failed to execute. - A patch can raise a `PatchException` at any time of execution to indicate that the patch failed to execute.
## ⏭️ What's next ## ⏭️ What's next

View File

@ -20,16 +20,51 @@ import kotlin.reflect.typeOf
* @constructor Create a new [Option]. * @constructor Create a new [Option].
*/ */
@Suppress("MemberVisibilityCanBePrivate", "unused") @Suppress("MemberVisibilityCanBePrivate", "unused")
class Option<T> @PublishedApi internal constructor( class Option<T>
@PublishedApi
@Deprecated("Use the constructor with the name instead of a key instead.")
internal constructor(
@Deprecated("Use the name property instead.")
val key: String, val key: String,
val default: T? = null, val default: T? = null,
val values: Map<String, T?>? = null, val values: Map<String, T?>? = null,
@Deprecated("Use the name property instead.")
val title: String? = null, val title: String? = null,
val description: String? = null, val description: String? = null,
val required: Boolean = false, val required: Boolean = false,
val type: KType, val type: KType,
val validator: Option<T>.(T?) -> Boolean = { true }, val validator: Option<T>.(T?) -> Boolean = { true },
) { ) {
/**
* The name.
*/
val name = key
/**
* An option.
*
* @param T The value type of the option.
* @param name The name.
* @param default The default value.
* @param values Eligible option values mapped to a human-readable name.
* @param description A description.
* @param required Whether the option is required.
* @param type The type of the option value (to handle type erasure).
* @param validator The function to validate the option value.
*
* @constructor Create a new [Option].
*/
@PublishedApi
internal constructor(
name: String,
default: T? = null,
values: Map<String, T?>? = null,
description: String? = null,
required: Boolean = false,
type: KType,
validator: Option<T>.(T?) -> Boolean = { true },
) : this(name, default, values, name, description, required, type, validator)
/** /**
* The value of the [Option]. * The value of the [Option].
*/ */
@ -109,7 +144,7 @@ class Option<T> @PublishedApi internal constructor(
class Options internal constructor( class Options internal constructor(
private val options: Map<String, Option<*>>, private val options: Map<String, Option<*>>,
) : Map<String, Option<*>> by options { ) : Map<String, Option<*>> by options {
internal constructor(options: Set<Option<*>>) : this(options.associateBy { it.key }) internal constructor(options: Set<Option<*>>) : this(options.associateBy { it.name })
/** /**
* Set an option's value. * Set an option's value.
@ -856,14 +891,14 @@ sealed class OptionException(errorMessage: String) : Exception(errorMessage, nul
* *
* @param value The value that failed validation. * @param value The value that failed validation.
*/ */
class ValueValidationException(value: Any?, option: Option<*>) : OptionException("The option value \"$value\" failed validation for ${option.key}") class ValueValidationException(value: Any?, option: Option<*>) : OptionException("The option value \"$value\" failed validation for ${option.name}")
/** /**
* An exception thrown when a value is required but null was passed. * An exception thrown when a value is required but null was passed.
* *
* @param option The [Option] that requires a value. * @param option The [Option] that requires a value.
*/ */
class ValueRequiredException(option: Option<*>) : OptionException("The option ${option.key} requires a value, but the value was null") class ValueRequiredException(option: Option<*>) : OptionException("The option ${option.name} requires a value, but the value was null")
/** /**
* An exception thrown when a [Option] is not found. * An exception thrown when a [Option] is not found.