From 433ba4b58fe3eed9dc302b4ed5f90e208651aedc Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Thu, 22 Sep 2022 23:39:08 +0600 Subject: [PATCH] argumentOrNull/argumentOrThrow --- CHANGELOG.md | 3 + common/build.gradle | 1 + .../ArgumentPropertyNullableDelegate.kt | 76 +++++++++++++++++++ gradle/libs.versions.toml | 2 + 4 files changed, 82 insertions(+) create mode 100644 common/src/main/kotlin/dev/inmo/micro_utils/common/ArgumentPropertyNullableDelegate.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index c00cd86d909..caa403afbaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ * `Android AppCompat`: `1.4.2` -> `1.5.1` * Android Compile SDK: 32 -> 33 * Android Build Tools: 32.0.0 -> 33.0.0 +* `Common`: + * `Android`: + * Add `argumentOrNull`/`argumentOrThrow` delegates for fragments * `Coroutines`: * Rewrite `awaitFirstWithDeferred` onto `CompletableDeferred` instead of coroutines suspending diff --git a/common/build.gradle b/common/build.gradle index 14324f2f227..880abb6a3a2 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -16,6 +16,7 @@ kotlin { androidMain { dependencies { api project(":micro_utils.coroutines") + api libs.android.fragment } } } diff --git a/common/src/main/kotlin/dev/inmo/micro_utils/common/ArgumentPropertyNullableDelegate.kt b/common/src/main/kotlin/dev/inmo/micro_utils/common/ArgumentPropertyNullableDelegate.kt new file mode 100644 index 00000000000..07d4abeab2a --- /dev/null +++ b/common/src/main/kotlin/dev/inmo/micro_utils/common/ArgumentPropertyNullableDelegate.kt @@ -0,0 +1,76 @@ +package dev.inmo.micro_utils.common + +import android.os.Bundle +import android.os.Parcelable +import androidx.fragment.app.Fragment +import java.io.Serializable +import kotlin.reflect.KProperty + +object ArgumentPropertyNullableDelegate { + operator fun getValue(thisRef: Fragment, property: KProperty<*>): T? { + val arguments = thisRef.arguments ?: return null + val key = property.name + return when (property.getter.returnType.classifier) { + // Scalars + String::class -> arguments.getString(key) + Boolean::class -> arguments.getBoolean(key) + Byte::class -> arguments.getByte(key) + Char::class -> arguments.getChar(key) + Double::class -> arguments.getDouble(key) + Float::class -> arguments.getFloat(key) + Int::class -> arguments.getInt(key) + Long::class -> arguments.getLong(key) + Short::class -> arguments.getShort(key) + + // References + Bundle::class -> arguments.getBundle(key) + CharSequence::class -> arguments.getCharSequence(key) + Parcelable::class -> arguments.getParcelable(key) + + // Scalar arrays + BooleanArray::class -> arguments.getBooleanArray(key) + ByteArray::class -> arguments.getByteArray(key) + CharArray::class -> arguments.getCharArray(key) + DoubleArray::class -> arguments.getDoubleArray(key) + FloatArray::class -> arguments.getFloatArray(key) + IntArray::class -> arguments.getIntArray(key) + LongArray::class -> arguments.getLongArray(key) + ShortArray::class -> arguments.getShortArray(key) + Array::class -> { + val componentType = property.returnType.classifier ?.javaClass ?.componentType!! + @Suppress("UNCHECKED_CAST") // Checked by reflection. + when { + Parcelable::class.java.isAssignableFrom(componentType) -> { + arguments.getParcelableArray(key) + } + String::class.java.isAssignableFrom(componentType) -> { + arguments.getStringArray(key) + } + CharSequence::class.java.isAssignableFrom(componentType) -> { + arguments.getCharSequenceArray(key) + } + Serializable::class.java.isAssignableFrom(componentType) -> { + arguments.getSerializable(key) + } + else -> { + val valueType = componentType.canonicalName + throw IllegalArgumentException( + "Illegal value array type $valueType for key \"$key\"" + ) + } + } + } + Serializable::class -> arguments.getSerializable(key) + else -> null + } as? T + } +} + +object ArgumentPropertyNonNullableDelegate { + operator fun getValue(thisRef: Fragment, property: KProperty<*>): T { + return ArgumentPropertyNullableDelegate.getValue(thisRef, property)!! + } +} + +fun argumentOrNull() = ArgumentPropertyNullableDelegate +fun argumentOrThrow() = ArgumentPropertyNonNullableDelegate diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1000475f46d..a8b63739d6e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -23,6 +23,7 @@ dexcount = "3.1.0" android-coreKtx = "1.9.0" android-recyclerView = "1.2.1" android-appCompat = "1.5.1" +android-fragment = "1.5.3" android-espresso = "3.4.0" android-test = "1.1.3" @@ -71,6 +72,7 @@ jb-exposed = { module = "org.jetbrains.exposed:exposed-core", version.ref = "jb- android-coreKtx = { module = "androidx.core:core-ktx", version.ref = "android-coreKtx" } android-recyclerView = { module = "androidx.recyclerview:recyclerview", version.ref = "android-recyclerView" } android-appCompat-resources = { module = "androidx.appcompat:appcompat-resources", version.ref = "android-appCompat" } +android-fragment = { module = "androidx.fragment:fragment", version.ref = "android-fragment" } android-espresso = { module = "androidx.test.espresso:espresso-core", version.ref = "android-espresso" } android-test-junit = { module = "androidx.test.ext:junit", version.ref = "android-test" }