forked from GitLiveApp/firebase-kotlin-sdk
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy path_encoders.kt
83 lines (75 loc) · 2.76 KB
/
_encoders.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/*
* Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license.
*/
package dev.gitlive.firebase
import kotlinx.serialization.descriptors.PolymorphicKind
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.StructureKind
import kotlin.js.Json
import kotlin.js.json
actual data class EncodedObject(private val keyValues: List<Pair<String, Any?>>) {
actual companion object {
actual val emptyEncodedObject: EncodedObject = EncodedObject(emptyList())
}
actual val raw get() = keyValues.toMap()
val json get() = json(*keyValues.toTypedArray())
}
@PublishedApi
internal actual fun List<Pair<String, Any?>>.asEncodedObject() = EncodedObject(this)
@PublishedApi
internal actual fun Any.asNativeMap(): Map<*, *>? {
val json = when (this) {
is Number -> null
is Boolean -> null
is String -> null
is Map<*, *> -> {
if (keys.all { it is String }) {
this as Json
} else {
null
}
}
is Collection<*> -> null
is Array<*> -> null
else -> {
this as Json
}
} ?: return null
val mutableMap = mutableMapOf<String, Any?>()
for (key in js("Object").keys(json)) {
mutableMap[key] = json[key]
}
return mutableMap.toMap()
}
actual fun FirebaseEncoder.structureEncoder(descriptor: SerialDescriptor): FirebaseCompositeEncoder = when(descriptor.kind) {
StructureKind.LIST -> encodeAsList(descriptor)
StructureKind.MAP -> {
val map = json()
var lastKey = ""
value = map
FirebaseCompositeEncoder(settings) { _, index, value ->
if (index % 2 == 0) {
lastKey = (value as? String) ?: JSON.stringify(value)
} else {
map[lastKey] = value
}
}
}
StructureKind.CLASS, StructureKind.OBJECT -> encodeAsMap(descriptor)
is PolymorphicKind -> encodeAsMap(descriptor)
else -> TODO("The firebase-kotlin-sdk does not support $descriptor for serialization yet")
}
private fun FirebaseEncoder.encodeAsList(descriptor: SerialDescriptor): FirebaseCompositeEncoder = Array<Any?>(descriptor.elementsCount) { null }
.also { value = it }
.let { FirebaseCompositeEncoder(settings) { _, index, value -> it[index] = value } }
private fun FirebaseEncoder.encodeAsMap(descriptor: SerialDescriptor): FirebaseCompositeEncoder = json()
.also { value = it }
.let {
FirebaseCompositeEncoder(
settings,
setPolymorphicType = { discriminator, type ->
it[discriminator] = type
},
set = { _, index, value -> it[descriptor.getElementName(index)] = value }
)
}