From fbb09f38dce49adc7f63b71bdf2df2ef0b84db04 Mon Sep 17 00:00:00 2001 From: Sculas Date: Tue, 2 Aug 2022 00:31:00 +0200 Subject: [PATCH] feat: patch options (#81) * feat: Patch Options * refactor: remove delegate property * feat: List patch options * refactor: add setter example to PatchOptionsUsage.kt * docs: add docs for PatchOptions * docs: tidy docs --- .../app/revanced/patcher/patch/Patch.kt | 5 + .../app/revanced/patcher/patch/PatchOption.kt | 100 ++++++++++++++++++ .../patcher/usage/PatchOptionsUsage.kt | 30 ++++++ .../usage/bytecode/ExampleBytecodePatch.kt | 16 +++ 4 files changed, 151 insertions(+) create mode 100644 src/main/kotlin/app/revanced/patcher/patch/PatchOption.kt create mode 100644 src/test/kotlin/app/revanced/patcher/usage/PatchOptionsUsage.kt diff --git a/src/main/kotlin/app/revanced/patcher/patch/Patch.kt b/src/main/kotlin/app/revanced/patcher/patch/Patch.kt index e48c6b3..53a3609 100644 --- a/src/main/kotlin/app/revanced/patcher/patch/Patch.kt +++ b/src/main/kotlin/app/revanced/patcher/patch/Patch.kt @@ -17,4 +17,9 @@ abstract class Patch { * The main function of the [Patch] which the patcher will call. */ abstract fun execute(data: @UnsafeVariance T): PatchResult + + /** + * A list of [PatchOption]s. + */ + open val options: Iterable> = listOf() } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patcher/patch/PatchOption.kt b/src/main/kotlin/app/revanced/patcher/patch/PatchOption.kt new file mode 100644 index 0000000..216e881 --- /dev/null +++ b/src/main/kotlin/app/revanced/patcher/patch/PatchOption.kt @@ -0,0 +1,100 @@ +package app.revanced.patcher.patch + +/** + * A [Patch] option. + * @param key Unique identifier of the option. Example: _`settings.microg.enabled`_ + * @param default The default value of the option. + * @param title A human-readable title of the option. Example: _MicroG Settings_ + * @param description A human-readable description of the option. Example: _Settings integration for MicroG._ + * @param required Whether the option is required. + */ +@Suppress("MemberVisibilityCanBePrivate") +sealed class PatchOption( + val key: String, + default: T?, + val title: String, + val description: String, + val required: Boolean +) { + var value: T? = default + + /** + * A [PatchOption] representing a [String]. + * @see PatchOption + */ + class StringOption( + key: String, + default: String?, + title: String, + description: String, + required: Boolean = false + ) : PatchOption( + key, default, title, description, required + ) + + /** + * A [PatchOption] representing a [Boolean]. + * @see PatchOption + */ + class BooleanOption( + key: String, + default: Boolean?, + title: String, + description: String, + required: Boolean = false + ) : PatchOption( + key, default, title, description, required + ) + + /** + * A [PatchOption] with a list of allowed options. + * @param options A list of allowed options for the [ListOption]. + * @see PatchOption + */ + sealed class ListOption( + key: String, + default: E?, + val options: Iterable, + title: String, + description: String, + required: Boolean = false + ) : PatchOption( + key, default, title, description, required + ) { + init { + if (default !in options) { + throw IllegalStateException("Default option must be an allowed options") + } + } + } + + /** + * A [ListOption] of type [String]. + * @see ListOption + */ + class StringListOption( + key: String, + default: String?, + options: Iterable, + title: String, + description: String, + required: Boolean = false + ) : ListOption( + key, default, options, title, description, required + ) + + /** + * A [ListOption] of type [Int]. + * @see ListOption + */ + class IntListOption( + key: String, + default: Int?, + options: Iterable, + title: String, + description: String, + required: Boolean = false + ) : ListOption( + key, default, options, title, description, required + ) +} \ No newline at end of file diff --git a/src/test/kotlin/app/revanced/patcher/usage/PatchOptionsUsage.kt b/src/test/kotlin/app/revanced/patcher/usage/PatchOptionsUsage.kt new file mode 100644 index 0000000..2828e45 --- /dev/null +++ b/src/test/kotlin/app/revanced/patcher/usage/PatchOptionsUsage.kt @@ -0,0 +1,30 @@ +package app.revanced.patcher.usage + +import app.revanced.patcher.patch.PatchOption +import app.revanced.patcher.usage.bytecode.ExampleBytecodePatch + +fun patchOptionsUsage() { + val options = ExampleBytecodePatch().options + for (option in options) { + when (option) { + is PatchOption.StringOption -> { + option.value = "Hello World" + } + is PatchOption.BooleanOption -> { + option.value = false + } + is PatchOption.StringListOption -> { + option.value = option.options.first() + for (choice in option.options) { + println(choice) + } + } + is PatchOption.IntListOption -> { + option.value = option.options.first() + for (choice in option.options) { + println(choice) + } + } + } + } +} \ No newline at end of file diff --git a/src/test/kotlin/app/revanced/patcher/usage/bytecode/ExampleBytecodePatch.kt b/src/test/kotlin/app/revanced/patcher/usage/bytecode/ExampleBytecodePatch.kt index 9b6bf0f..c4d91fe 100644 --- a/src/test/kotlin/app/revanced/patcher/usage/bytecode/ExampleBytecodePatch.kt +++ b/src/test/kotlin/app/revanced/patcher/usage/bytecode/ExampleBytecodePatch.kt @@ -7,6 +7,7 @@ import app.revanced.patcher.data.impl.BytecodeData import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.replaceInstruction +import app.revanced.patcher.patch.PatchOption import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.annotations.DependencyType @@ -162,4 +163,19 @@ class ExampleBytecodePatch : BytecodePatch(listOf(ExampleFingerprint)) { ) ) } + + override val options = listOf( + PatchOption.StringOption( + "key", "default", "title", "description", true + ), + PatchOption.BooleanOption( + "key", true, "title", "description" // required defaults to false + ), + PatchOption.StringListOption( + "key", "TEST", listOf("TEST", "TEST1", "TEST2"), "title", "description" + ), + PatchOption.IntListOption( + "key", 1, listOf(1, 2, 3), "title", "description" + ), + ) }