diff --git a/app/src/main/java/com/aurora/store/data/serializers/LocaleSerializer.kt b/app/src/main/java/com/aurora/store/data/serializers/LocaleSerializer.kt new file mode 100644 index 000000000..e05f7c1bf --- /dev/null +++ b/app/src/main/java/com/aurora/store/data/serializers/LocaleSerializer.kt @@ -0,0 +1,56 @@ +/* + * SPDX-FileCopyrightText: 2025 The Calyx Institute + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.aurora.store.data.serializers + +import kotlinx.serialization.KSerializer +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.descriptors.buildClassSerialDescriptor +import kotlinx.serialization.descriptors.element +import kotlinx.serialization.encoding.CompositeDecoder +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import kotlinx.serialization.encoding.decodeStructure +import kotlinx.serialization.encoding.encodeStructure +import java.util.Locale + +/** + * Serializer for [Locale] for working with Kotlin's Serialization library + */ +object LocaleSerializer : KSerializer { + override val descriptor: SerialDescriptor = buildClassSerialDescriptor("Locale") { + element("language") + element("region") + } + + override fun serialize(encoder: Encoder, value: Locale) { + return encoder.encodeStructure(descriptor) { + encodeStringElement(descriptor, 0, value.language) + encodeStringElement(descriptor, 1, value.country) + } + } + + override fun deserialize(decoder: Decoder): Locale { + return decoder.decodeStructure(descriptor) { + var language: String? = null + var region: String? = null + + while (true) { + when (val index = decodeElementIndex(descriptor)) { + 0 -> language = decodeStringElement(descriptor, 0) + 1 -> region = decodeStringElement(descriptor, 1) + CompositeDecoder.DECODE_DONE -> break + else -> error("Unexpected index: $index") + } + } + + require(!language.isNullOrBlank() && !region.isNullOrBlank()) + Locale.Builder() + .setLanguage(language) + .setRegion(region) + .build() + } + } +} diff --git a/app/src/main/java/com/aurora/store/data/serializers/PropertiesSerializer.kt b/app/src/main/java/com/aurora/store/data/serializers/PropertiesSerializer.kt new file mode 100644 index 000000000..c92906e2c --- /dev/null +++ b/app/src/main/java/com/aurora/store/data/serializers/PropertiesSerializer.kt @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2025 The Calyx Institute + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.aurora.store.data.serializers + +import kotlinx.serialization.KSerializer +import kotlinx.serialization.builtins.MapSerializer +import kotlinx.serialization.builtins.serializer +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import java.util.Properties + +/** + * Serializer for [Properties] for working with Kotlin's Serialization library + */ +object PropertiesSerializer : KSerializer { + override val descriptor: SerialDescriptor = + MapSerializer(String.serializer(), String.serializer()).descriptor + + override fun serialize(encoder: Encoder, value: Properties) { + val map = value.stringPropertyNames().associateWith { value.getProperty(it) } + MapSerializer(String.serializer(), String.serializer()).serialize(encoder, map) + } + + override fun deserialize(decoder: Decoder): Properties { + val map = MapSerializer(String.serializer(), String.serializer()).deserialize(decoder) + return Properties().apply { putAll(map) } + } +} diff --git a/app/src/main/java/com/aurora/store/module/CommonModule.kt b/app/src/main/java/com/aurora/store/module/CommonModule.kt index b66826c62..34730000c 100644 --- a/app/src/main/java/com/aurora/store/module/CommonModule.kt +++ b/app/src/main/java/com/aurora/store/module/CommonModule.kt @@ -1,10 +1,14 @@ package com.aurora.store.module +import com.aurora.store.data.serializers.LocaleSerializer +import com.aurora.store.data.serializers.PropertiesSerializer import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import kotlinx.serialization.json.Json +import kotlinx.serialization.modules.SerializersModule +import kotlinx.serialization.modules.contextual import javax.inject.Singleton @Module @@ -14,10 +18,16 @@ object CommonModule { @Singleton @Provides fun providesJsonInstance(): Json { + val module = SerializersModule { + contextual(LocaleSerializer) + contextual(PropertiesSerializer) + } + return Json { prettyPrint = true ignoreUnknownKeys = true coerceInputValues = true + serializersModule = module } } }