diff --git a/enro-common/src/androidMain/kotlin/dev/enro/metadataKeyName.android.kt b/enro-common/src/androidMain/kotlin/dev/enro/metadataKeyName.android.kt new file mode 100644 index 00000000..e33ec857 --- /dev/null +++ b/enro-common/src/androidMain/kotlin/dev/enro/metadataKeyName.android.kt @@ -0,0 +1,9 @@ +package dev.enro + +import kotlin.reflect.KClass + +internal actual fun metadataKeyName(kClass: KClass<*>): String { + return kClass.qualifiedName + ?: kClass.simpleName + ?: error("MetadataKey class must have a qualifiedName or simpleName") +} diff --git a/enro-common/src/commonMain/kotlin/dev/enro/NavigationKey.kt b/enro-common/src/commonMain/kotlin/dev/enro/NavigationKey.kt index c2760cf0..0f01b954 100644 --- a/enro-common/src/commonMain/kotlin/dev/enro/NavigationKey.kt +++ b/enro-common/src/commonMain/kotlin/dev/enro/NavigationKey.kt @@ -224,7 +224,7 @@ public interface NavigationKey { public val default: T, ) { public val name: String by lazy { - this::class.qualifiedName ?: error("MetadataKeys must have a valid qualifiedName") + metadataKeyName(this::class) } } diff --git a/enro-common/src/commonMain/kotlin/dev/enro/metadataKeyName.kt b/enro-common/src/commonMain/kotlin/dev/enro/metadataKeyName.kt new file mode 100644 index 00000000..311f7b74 --- /dev/null +++ b/enro-common/src/commonMain/kotlin/dev/enro/metadataKeyName.kt @@ -0,0 +1,21 @@ +package dev.enro + +import kotlin.reflect.KClass + +/** + * Stable string identifier for a [NavigationKey.MetadataKey]'s class. + * Used as the storage key inside [NavigationKey.Metadata] and persisted + * across saved-state round-trips, so the identifier must be: + * + * - **Stable across runs** — serialised metadata must restore to the + * same logical key on next launch. + * - **Unique per MetadataKey class** — two different MetadataKey objects + * must not collide. + * + * On every target except Kotlin/JS this is `KClass.qualifiedName`. On + * Kotlin/JS, `qualifiedName` is unsupported by the Kotlin reflection + * API, so we fall back to `simpleName`. The JS fallback is correct for + * the common `object MyKey : MetadataKey<...>` pattern as long as the + * `MyKey` simple names are unique within the app. + */ +internal expect fun metadataKeyName(kClass: KClass<*>): String diff --git a/enro-common/src/desktopMain/kotlin/dev/enro/metadataKeyName.desktop.kt b/enro-common/src/desktopMain/kotlin/dev/enro/metadataKeyName.desktop.kt new file mode 100644 index 00000000..e33ec857 --- /dev/null +++ b/enro-common/src/desktopMain/kotlin/dev/enro/metadataKeyName.desktop.kt @@ -0,0 +1,9 @@ +package dev.enro + +import kotlin.reflect.KClass + +internal actual fun metadataKeyName(kClass: KClass<*>): String { + return kClass.qualifiedName + ?: kClass.simpleName + ?: error("MetadataKey class must have a qualifiedName or simpleName") +} diff --git a/enro-common/src/iosMain/kotlin/dev/enro/metadataKeyName.ios.kt b/enro-common/src/iosMain/kotlin/dev/enro/metadataKeyName.ios.kt new file mode 100644 index 00000000..e33ec857 --- /dev/null +++ b/enro-common/src/iosMain/kotlin/dev/enro/metadataKeyName.ios.kt @@ -0,0 +1,9 @@ +package dev.enro + +import kotlin.reflect.KClass + +internal actual fun metadataKeyName(kClass: KClass<*>): String { + return kClass.qualifiedName + ?: kClass.simpleName + ?: error("MetadataKey class must have a qualifiedName or simpleName") +} diff --git a/enro-common/src/jsMain/kotlin/dev/enro/metadataKeyName.js.kt b/enro-common/src/jsMain/kotlin/dev/enro/metadataKeyName.js.kt new file mode 100644 index 00000000..95837709 --- /dev/null +++ b/enro-common/src/jsMain/kotlin/dev/enro/metadataKeyName.js.kt @@ -0,0 +1,12 @@ +package dev.enro + +import kotlin.reflect.KClass + +// Kotlin/JS reflection does not expose qualifiedName. simpleName is the +// only stable identifier available — collisions across packages are +// possible in principle, but the recommended `object MyKey : MetadataKey<…>` +// pattern produces a unique simpleName per definition site. +internal actual fun metadataKeyName(kClass: KClass<*>): String { + return kClass.simpleName + ?: error("MetadataKey class must have a simpleName on Kotlin/JS") +} diff --git a/enro-common/src/wasmJsMain/kotlin/dev/enro/metadataKeyName.wasmJs.kt b/enro-common/src/wasmJsMain/kotlin/dev/enro/metadataKeyName.wasmJs.kt new file mode 100644 index 00000000..e33ec857 --- /dev/null +++ b/enro-common/src/wasmJsMain/kotlin/dev/enro/metadataKeyName.wasmJs.kt @@ -0,0 +1,9 @@ +package dev.enro + +import kotlin.reflect.KClass + +internal actual fun metadataKeyName(kClass: KClass<*>): String { + return kClass.qualifiedName + ?: kClass.simpleName + ?: error("MetadataKey class must have a qualifiedName or simpleName") +}