diff --git a/CHANGELOG.md b/CHANGELOG.md index 99d772fd305..812077ea0d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.20.32 + +* `Versions`: + * `Okio`: `3.7.0` -> `3.8.0` +* `Resources`: + * Make `StringResource` serializable + * Add several variants of builder usages + ## 0.20.31 * `Versions`: diff --git a/gradle.properties b/gradle.properties index 98a9ff0b8b7..456d202d9c8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,5 +15,5 @@ crypto_js_version=4.1.1 # Project data group=dev.inmo -version=0.20.31 -android_code_version=237 +version=0.20.32 +android_code_version=238 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f9b61e45c5f..5818b8f5c5e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -19,7 +19,7 @@ gh-release = "2.5.2" koin = "3.5.3" -okio = "3.7.0" +okio = "3.8.0" ksp = "1.9.22-1.0.17" kotlin-poet = "1.16.0" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a5952066425..17655d0ef2b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/resources/src/commonMain/kotlin/StringResource.kt b/resources/src/commonMain/kotlin/StringResource.kt index d87526fc691..397afa6af27 100644 --- a/resources/src/commonMain/kotlin/StringResource.kt +++ b/resources/src/commonMain/kotlin/StringResource.kt @@ -1,6 +1,11 @@ package dev.inmo.micro_utils.strings import dev.inmo.micro_utils.language_codes.IetfLang +import kotlinx.serialization.KSerializer +import kotlinx.serialization.Serializable +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder /** * Use this class as a type of your strings object fields. For example: @@ -15,9 +20,10 @@ import dev.inmo.micro_utils.language_codes.IetfLang * * @see buildStringResource */ -class StringResource( +@Serializable(StringResource.Companion::class) +data class StringResource( val default: String, - val map: Map> + val translations: Map> ) { class Builder( var default: String @@ -31,11 +37,18 @@ class StringResource( infix fun IetfLang.variant(value: () -> String) = this variant lazy(value) infix fun IetfLang.variant(value: String) = this variant lazyOf(value) + operator fun IetfLang.invoke(value: () -> String) = this variant value + operator fun IetfLang.invoke(value: String) = this variant value + infix fun String.variant(value: Lazy) = IetfLang(this) variant value infix fun String.variant(value: () -> String) = IetfLang(this) variant lazy(value) infix fun String.variant(value: String) = this variant lazyOf(value) + + operator fun String.invoke(value: () -> String) = this variant value + operator fun String.invoke(value: String) = this variant value + fun build() = StringResource(default, map.toMap()) } @@ -43,17 +56,48 @@ class StringResource( if (languageCode == null) { return default } - map[languageCode] ?.let { return it.value } + translations[languageCode] ?.let { return it.value } return languageCode.parentLang ?.let { - map[it] ?.value + translations[it] ?.value } ?: default } + + companion object : KSerializer { + @Serializable + private class Surrogate( + val default: String, + val translations: Map + ) + + override val descriptor: SerialDescriptor + get() = Surrogate.serializer().descriptor + + override fun deserialize(decoder: Decoder): StringResource { + val surrogate = Surrogate.serializer().deserialize(decoder) + return StringResource( + surrogate.default, + surrogate.translations.map { IetfLang(it.key) to lazyOf(it.value) }.toMap() + ) + } + + override fun serialize(encoder: Encoder, value: StringResource) { + Surrogate.serializer().serialize( + encoder, + Surrogate( + value.default, + value.translations.map { + it.key.code to it.value.value + }.toMap() + ) + ) + } + } } inline fun buildStringResource( default: String, - builder: StringResource.Builder.() -> Unit + builder: StringResource.Builder.() -> Unit = {} ): StringResource { return StringResource.Builder(default).apply(builder).build() }