Skip to content

Commit

Permalink
Help the polymorphic decoder determine the Serializer to use by alway…
Browse files Browse the repository at this point in the history
…s putting the type discriminator first
  • Loading branch information
janseeger committed Mar 14, 2024
1 parent 0efb274 commit e717304
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ class StringMapToObjectDecoder(
super.endStructure(descriptor)
}

@Suppress("UNCHECKED_CAST")
override fun <T> decodeType(typeKey: String): T? {
@Suppress("UNCHECKED_CAST")
val currentData = (data[key] as? Map<String, Any>) ?: return null
return (currentData[typeKey] as? T)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,27 @@ inline fun <reified T : Any> DataSnapshot.toObjectWithSerializer(
customSerializers: SerializersModule = EmptySerializersModule()
): T = serializer.deserialize(StringMapToObjectDecoder(toObjectMap().unwrapRoot(), customSerializers))

@Suppress("UNNECESSARY_NOT_NULL_ASSERTION")
fun DataSnapshot.toObjectMap(): Pair<String, Any> =
(key ?: "root") to (if (hasChildren()) children.associate { it.toObjectMap() } else value)!!
fun DataSnapshot.toObjectMap(): Pair<String, Any> {
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<String, Any>.unwrapRoot() = second as Map<String, Any>

internal fun <A : Comparable<A>, B> Iterable<Pair<A, B>>.ensureTypeIsFirst(): Iterable<Pair<A, B>> =
sortedWith { a, b ->
when {
a.first == "type" -> -1
b.first == "type" -> 1
else -> a.first.compareTo(b.first)
}
}

0 comments on commit e717304

Please sign in to comment.