All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.StringResource.kt Maven / Gradle / Ivy

There is a newer version: 0.24.4
Show newest version
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:
 *
 * ```kotlin
 * object Strings {
 *     val someResource: StringResource
 * }
 * ```
 *
 * Use [buildStringResource] for useful creation of string resource
 *
 * @see buildStringResource
 */
@Serializable(StringResource.Companion::class)
data class StringResource(
    val default: String,
    val translations: Map>
) {
    class Builder(
        var default: String
    ) {
        private val map = mutableMapOf>()

        infix fun IetfLang.variant(value: Lazy) {
            map[this] = value
        }

        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())
    }

    fun translation(languageCode: IetfLang?): String {
        if (languageCode == null) {
            return default
        }
        translations[languageCode] ?.let { return it.value }

        return languageCode.parentLang ?.let {
            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 = {}
): StringResource {
    return StringResource.Builder(default).apply(builder).build()
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy