From e7173043a9897c2fc5fdbc4f716cf6400b6cda72 Mon Sep 17 00:00:00 2001 From: Jan Seeger Date: Thu, 14 Mar 2024 18:10:41 +0100 Subject: [PATCH] Help the polymorphic decoder determine the Serializer to use by always putting the type discriminator first --- .../common/StringMapToObjectDecoder.kt | 2 +- .../federmappe/realtimedb/DataSnapshotExt.kt | 24 ++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/common/src/main/kotlin/de/sipgate/federmappe/common/StringMapToObjectDecoder.kt b/common/src/main/kotlin/de/sipgate/federmappe/common/StringMapToObjectDecoder.kt index df3c374..7b80f6c 100644 --- a/common/src/main/kotlin/de/sipgate/federmappe/common/StringMapToObjectDecoder.kt +++ b/common/src/main/kotlin/de/sipgate/federmappe/common/StringMapToObjectDecoder.kt @@ -100,8 +100,8 @@ class StringMapToObjectDecoder( super.endStructure(descriptor) } + @Suppress("UNCHECKED_CAST") override fun decodeType(typeKey: String): T? { - @Suppress("UNCHECKED_CAST") val currentData = (data[key] as? Map) ?: return null return (currentData[typeKey] as? T) } diff --git a/realtimedb/src/main/kotlin/de/sipgate/federmappe/realtimedb/DataSnapshotExt.kt b/realtimedb/src/main/kotlin/de/sipgate/federmappe/realtimedb/DataSnapshotExt.kt index 5306ecd..0061310 100644 --- a/realtimedb/src/main/kotlin/de/sipgate/federmappe/realtimedb/DataSnapshotExt.kt +++ b/realtimedb/src/main/kotlin/de/sipgate/federmappe/realtimedb/DataSnapshotExt.kt @@ -24,9 +24,27 @@ inline fun DataSnapshot.toObjectWithSerializer( customSerializers: SerializersModule = EmptySerializersModule() ): T = serializer.deserialize(StringMapToObjectDecoder(toObjectMap().unwrapRoot(), customSerializers)) -@Suppress("UNNECESSARY_NOT_NULL_ASSERTION") -fun DataSnapshot.toObjectMap(): Pair = - (key ?: "root") to (if (hasChildren()) children.associate { it.toObjectMap() } else value)!! +fun DataSnapshot.toObjectMap(): Pair { + val key = key ?: "root" + val value = when { + hasChildren() -> children + .map(DataSnapshot::toObjectMap) + .ensureTypeIsFirst() + .toMap() + + else -> value + } + return key to value!! +} @Suppress("UNCHECKED_CAST") fun Pair.unwrapRoot() = second as Map + +internal fun , B> Iterable>.ensureTypeIsFirst(): Iterable> = + sortedWith { a, b -> + when { + a.first == "type" -> -1 + b.first == "type" -> 1 + else -> a.first.compareTo(b.first) + } + }