Skip to content

Commit 36a37c5

Browse files
committed
Working Timestamps and serverTimestamps on Android
1 parent c107342 commit 36a37c5

File tree

21 files changed

+342
-300
lines changed

21 files changed

+342
-300
lines changed

firebase-common/src/androidMain/kotlin/dev/gitlive/firebase/_decoders.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ import kotlinx.serialization.SerializationException
1010
import kotlinx.serialization.descriptors.SerialDescriptor
1111
import kotlinx.serialization.descriptors.StructureKind
1212

13-
actual fun FirebaseDecoder.structureDecoder(descriptor: SerialDescriptor, decodeDouble: (value: Any?) -> Double?): CompositeDecoder = when(descriptor.kind as StructureKind) {
13+
actual fun FirebaseDecoder.structureDecoder(descriptor: SerialDescriptor): CompositeDecoder = when(descriptor.kind as StructureKind) {
1414
StructureKind.CLASS, StructureKind.OBJECT -> (value as Map<*, *>).let { map ->
15-
FirebaseClassDecoder(decodeDouble, map.size, { map.containsKey(it) }) { desc, index -> map[desc.getElementName(index)] }
15+
FirebaseClassDecoder(map.size, { map.containsKey(it) }, {v -> getDecoder(v)}) { desc, index -> map[desc.getElementName(index)] }
1616
}
1717
StructureKind.LIST -> (value as List<*>).let {
18-
FirebaseCompositeDecoder(decodeDouble, it.size) { _, index -> it[index] }
18+
FirebaseCompositeDecoder(it.size, {v -> getDecoder(v)}) { _, index -> it[index] }
1919
}
2020
StructureKind.MAP -> (value as Map<*, *>).entries.toList().let {
21-
FirebaseCompositeDecoder(decodeDouble, it.size) { _, index -> it[index/2].run { if(index % 2 == 0) key else value } }
21+
FirebaseCompositeDecoder(it.size, {v -> getDecoder(v)}) { _, index -> it[index/2].run { if(index % 2 == 0) key else value } }
2222
}
2323
}

firebase-common/src/androidMain/kotlin/dev/gitlive/firebase/_encoders.kt

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,22 @@ import kotlin.collections.set
1212
actual fun FirebaseEncoder.structureEncoder(descriptor: SerialDescriptor): CompositeEncoder = when (descriptor.kind as StructureKind) {
1313
StructureKind.LIST -> mutableListOf<Any?>()
1414
.also { value = it }
15-
.let { FirebaseCompositeEncoder(shouldEncodeElementDefault, positiveInfinity) { _, index, value -> it.add(index, value) } }
15+
.let { FirebaseCompositeEncoder(shouldEncodeElementDefault, {getEncoder(shouldEncodeElementDefault)}) { _, index, value -> it.add(index, value) } }
1616
StructureKind.MAP -> mutableListOf<Any?>()
1717
.let {
1818
FirebaseCompositeEncoder(
1919
shouldEncodeElementDefault,
20-
positiveInfinity,
20+
{getEncoder(shouldEncodeElementDefault)},
2121
{ value = it.chunked(2).associate { (k, v) -> k to v } }) { _, _, value -> it.add(value) }
2222
}
23-
StructureKind.CLASS -> mutableMapOf<Any?, Any?>()
23+
StructureKind.OBJECT, StructureKind.CLASS -> mutableMapOf<Any?, Any?>()
2424
.also { value = it }
2525
.let {
26-
FirebaseCompositeEncoder(shouldEncodeElementDefault, positiveInfinity) { _, index, value ->
27-
it[descriptor.getElementName(index)] = value
26+
FirebaseCompositeEncoder(shouldEncodeElementDefault, {getEncoder(shouldEncodeElementDefault)}) { _, index, value ->
27+
it[descriptor.getElementName(
28+
index
29+
)] = value
2830
}
2931
}
30-
StructureKind.OBJECT -> {
31-
when (descriptor.serialName) {
32-
"firebaseTimestamp" -> FirebaseTimestampCompositeEncoder { value = it }
33-
else -> mutableMapOf<Any?, Any?>()
34-
.also { value = it }
35-
.let {
36-
FirebaseCompositeEncoder(shouldEncodeElementDefault, positiveInfinity) { _, index, value ->
37-
it[descriptor.getElementName(
38-
index
39-
)] = value
40-
}
41-
}
42-
}
43-
}
32+
4433
}

firebase-common/src/androidMain/kotlin/dev/gitlive/firebase/_types.kt

Lines changed: 0 additions & 5 deletions
This file was deleted.

firebase-common/src/commonMain/kotlin/dev/gitlive/firebase/decoders.kt

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,29 @@ import kotlinx.serialization.modules.SerializersModule
1616
import kotlinx.serialization.serializer
1717

1818
@Suppress("UNCHECKED_CAST")
19-
inline fun <reified T> decode(value: Any?, noinline decodeDouble: (value: Any?) -> Double? = { null }): T {
19+
inline fun <reified T> decode(value: Any?): T {
2020
val strategy = serializer<T>()
21-
return decode(strategy as DeserializationStrategy<T>, value, decodeDouble)
21+
return decode(strategy as DeserializationStrategy<T>, value)
2222
}
2323

24-
fun <T> decode(strategy: DeserializationStrategy<T>, value: Any?, decodeDouble: (value: Any?) -> Double? = { null }): T {
24+
fun <T> decode(strategy: DeserializationStrategy<T>, value: Any?): T {
2525
require(value != null || strategy.descriptor.isNullable) { "Value was null for non-nullable type ${strategy.descriptor.serialName}" }
26-
return FirebaseDecoder(value, decodeDouble).decodeSerializableValue(strategy)
26+
return FirebaseDecoder(value).decodeSerializableValue(strategy)
2727
}
2828

29-
expect fun FirebaseDecoder.structureDecoder(descriptor: SerialDescriptor, decodeDouble: (value: Any?) -> Double?): CompositeDecoder
29+
expect fun FirebaseDecoder.structureDecoder(descriptor: SerialDescriptor): CompositeDecoder
3030

31-
class FirebaseDecoder(internal val value: Any?, private val decodeDouble: (value: Any?) -> Double?) : Decoder {
31+
open class FirebaseDecoder(internal val value: Any?) : Decoder {
32+
open fun getDecoder(value: Any?) : FirebaseDecoder = FirebaseDecoder(value)
3233

3334
override val serializersModule: SerializersModule
3435
get() = EmptySerializersModule
3536

36-
override fun beginStructure(descriptor: SerialDescriptor) = structureDecoder(descriptor, decodeDouble)
37+
override fun beginStructure(descriptor: SerialDescriptor) = structureDecoder(descriptor)
3738

3839
override fun decodeString() = decodeString(value)
3940

40-
override fun decodeDouble() = decodeDouble(value, decodeDouble)
41+
override fun decodeDouble() = decodeDouble(value)
4142

4243
override fun decodeLong() = decodeLong(value)
4344

@@ -60,15 +61,15 @@ class FirebaseDecoder(internal val value: Any?, private val decodeDouble: (value
6061
override fun decodeNull() = decodeNull(value)
6162

6263
@ExperimentalSerializationApi
63-
override fun decodeInline(inlineDescriptor: SerialDescriptor) = FirebaseDecoder(value, decodeDouble)
64+
override fun decodeInline(inlineDescriptor: SerialDescriptor) = FirebaseDecoder(value)
6465
}
6566

6667
class FirebaseClassDecoder(
67-
decodeDouble: (value: Any?) -> Double?,
6868
size: Int,
6969
private val containsKey: (name: String) -> Boolean,
70+
getDecoder: (Any?)->FirebaseDecoder,
7071
get: (descriptor: SerialDescriptor, index: Int) -> Any?
71-
) : FirebaseCompositeDecoder(decodeDouble, size, get) {
72+
) : FirebaseCompositeDecoder(size, getDecoder, get) {
7273
private var index: Int = 0
7374

7475
override fun decodeSequentially() = false
@@ -81,8 +82,8 @@ class FirebaseClassDecoder(
8182
}
8283

8384
open class FirebaseCompositeDecoder constructor(
84-
private val decodeDouble: (value: Any?) -> Double?,
8585
private val size: Int,
86+
private val getDecoder: (Any?)->FirebaseDecoder,
8687
private val get: (descriptor: SerialDescriptor, index: Int) -> Any?
8788
): CompositeDecoder {
8889

@@ -99,15 +100,15 @@ open class FirebaseCompositeDecoder constructor(
99100
index: Int,
100101
deserializer: DeserializationStrategy<T>,
101102
previousValue: T?
102-
) = deserializer.deserialize(FirebaseDecoder(get(descriptor, index), decodeDouble))
103+
) = deserializer.deserialize(getDecoder(get(descriptor, index)))
103104

104105
override fun decodeBooleanElement(descriptor: SerialDescriptor, index: Int) = decodeBoolean(get(descriptor, index))
105106

106107
override fun decodeByteElement(descriptor: SerialDescriptor, index: Int) = decodeByte(get(descriptor, index))
107108

108109
override fun decodeCharElement(descriptor: SerialDescriptor, index: Int) = decodeChar(get(descriptor, index))
109110

110-
override fun decodeDoubleElement(descriptor: SerialDescriptor, index: Int) = decodeDouble(get(descriptor, index), decodeDouble)
111+
override fun decodeDoubleElement(descriptor: SerialDescriptor, index: Int) = decodeDouble(get(descriptor, index))
111112

112113
override fun decodeFloatElement(descriptor: SerialDescriptor, index: Int) = decodeFloat(get(descriptor, index))
113114

@@ -133,15 +134,15 @@ open class FirebaseCompositeDecoder constructor(
133134

134135
@ExperimentalSerializationApi
135136
override fun decodeInlineElement(descriptor: SerialDescriptor, index: Int): Decoder =
136-
FirebaseDecoder(get(descriptor, index), decodeDouble)
137+
getDecoder(get(descriptor, index))
137138
}
138139

139140
private fun decodeString(value: Any?) = value.toString()
140141

141-
private fun decodeDouble(value: Any?, decodeDouble: (value: Any?) -> Double?) = when(value) {
142+
private fun decodeDouble(value: Any?) = when(value) {
142143
is Number -> value.toDouble()
143144
is String -> value.toDouble()
144-
else -> decodeDouble(value) ?: throw SerializationException("Expected $value to be double")
145+
else -> throw SerializationException("Expected $value to be double")
145146
}
146147

147148
private fun decodeLong(value: Any?) = when(value) {

firebase-common/src/commonMain/kotlin/dev/gitlive/firebase/encoders.kt

Lines changed: 15 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,24 @@ import kotlinx.serialization.modules.SerializersModule
1515
fun <T> encode(
1616
strategy: SerializationStrategy<T>,
1717
value: T,
18-
shouldEncodeElementDefault: Boolean,
19-
positiveInfinity: Any = Double.POSITIVE_INFINITY
18+
shouldEncodeElementDefault: Boolean
2019
): Any? =
21-
FirebaseEncoder(shouldEncodeElementDefault, positiveInfinity).apply {
20+
FirebaseEncoder(shouldEncodeElementDefault).apply {
2221
encodeSerializableValue(
2322
strategy,
2423
value
2524
)
2625
}.value//.also { println("encoded $it") }
2726

28-
inline fun <reified T> encode(value: T, shouldEncodeElementDefault: Boolean, positiveInfinity: Any = Double.POSITIVE_INFINITY): Any? = value?.let {
29-
FirebaseEncoder(shouldEncodeElementDefault, positiveInfinity).apply { encodeSerializableValue(it.firebaseSerializer(), it) }.value
27+
@Suppress("UNCHECKED_CAST")
28+
inline fun <reified T> encode(value: T, shouldEncodeElementDefault: Boolean): Any? = value?.let {
29+
FirebaseEncoder(shouldEncodeElementDefault).apply { encodeSerializableValue(firebaseSerializer(it) as SerializationStrategy<T>, it) }.value
3030
}
3131

3232
expect fun FirebaseEncoder.structureEncoder(descriptor: SerialDescriptor): CompositeEncoder
3333

34-
class FirebaseEncoder(internal val shouldEncodeElementDefault: Boolean, positiveInfinity: Any) : TimestampEncoder(positiveInfinity), Encoder {
34+
open class FirebaseEncoder(internal val shouldEncodeElementDefault: Boolean) : Encoder {
35+
open fun getEncoder(shouldEncodeElementDefault: Boolean): FirebaseEncoder = FirebaseEncoder(shouldEncodeElementDefault)
3536

3637
var value: Any? = null
3738

@@ -51,7 +52,7 @@ class FirebaseEncoder(internal val shouldEncodeElementDefault: Boolean, positive
5152
}
5253

5354
override fun encodeDouble(value: Double) {
54-
this.value = encodeTimestamp(value)
55+
this.value = value
5556
}
5657

5758
override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int) {
@@ -88,63 +89,15 @@ class FirebaseEncoder(internal val shouldEncodeElementDefault: Boolean, positive
8889

8990
@ExperimentalSerializationApi
9091
override fun encodeInline(inlineDescriptor: SerialDescriptor): Encoder =
91-
FirebaseEncoder(shouldEncodeElementDefault, positiveInfinity)
92-
}
93-
94-
abstract class TimestampEncoder(internal val positiveInfinity: Any) {
95-
fun encodeTimestamp(value: Double) = when (value) {
96-
Double.POSITIVE_INFINITY -> positiveInfinity
97-
else -> value
98-
}
99-
}
100-
101-
class FirebaseTimestampCompositeEncoder(val onSet: (Any)->Unit) : CompositeEncoder {
102-
var nanos: Int = 0
103-
var seconds: Long = 0
104-
105-
override val serializersModule = EmptySerializersModule
106-
107-
override fun encodeBooleanElement(descriptor: SerialDescriptor, index: Int, value: Boolean) = throw IllegalStateException()
108-
override fun encodeByteElement(descriptor: SerialDescriptor, index: Int, value: Byte) = throw IllegalStateException()
109-
override fun encodeCharElement(descriptor: SerialDescriptor, index: Int, value: Char) = throw IllegalStateException()
110-
override fun encodeDoubleElement(descriptor: SerialDescriptor, index: Int, value: Double) = throw IllegalStateException()
111-
override fun encodeFloatElement(descriptor: SerialDescriptor, index: Int, value: Float) = throw IllegalStateException()
112-
@ExperimentalSerializationApi
113-
override fun encodeInlineElement(descriptor: SerialDescriptor, index: Int): Encoder = throw IllegalStateException()
114-
115-
override fun encodeIntElement(descriptor: SerialDescriptor, index: Int, value: Int) {
116-
nanos = value
117-
}
118-
119-
override fun encodeLongElement(descriptor: SerialDescriptor, index: Int, value: Long) {
120-
seconds = value
121-
}
122-
123-
@ExperimentalSerializationApi
124-
override fun <T : Any> encodeNullableSerializableElement(
125-
descriptor: SerialDescriptor,
126-
index: Int,
127-
serializer: SerializationStrategy<T>,
128-
value: T?
129-
) = throw IllegalStateException()
130-
131-
override fun <T> encodeSerializableElement(descriptor: SerialDescriptor, index: Int, serializer: SerializationStrategy<T>, value: T) = throw IllegalStateException()
132-
133-
override fun encodeShortElement(descriptor: SerialDescriptor, index: Int, value: Short) = throw IllegalStateException()
134-
135-
override fun encodeStringElement(descriptor: SerialDescriptor, index: Int, value: String) = throw IllegalStateException()
136-
137-
override fun endStructure(descriptor: SerialDescriptor) {
138-
onSet(Timestamp(nanos, seconds).asNative())
139-
}
92+
getEncoder(shouldEncodeElementDefault)
14093
}
14194

14295
open class FirebaseCompositeEncoder constructor(
14396
private val shouldEncodeElementDefault: Boolean,
144-
positiveInfinity: Any,
97+
private val getEncoder: (Boolean)->FirebaseEncoder,
14598
private val end: () -> Unit = {},
14699
private val set: (descriptor: SerialDescriptor, index: Int, value: Any?) -> Unit
147-
) : TimestampEncoder(positiveInfinity), CompositeEncoder {
100+
) : CompositeEncoder {
148101

149102
override val serializersModule = EmptySerializersModule
150103

@@ -167,7 +120,7 @@ open class FirebaseCompositeEncoder constructor(
167120
descriptor,
168121
index,
169122
value?.let {
170-
FirebaseEncoder(shouldEncodeElementDefault, positiveInfinity).apply {
123+
getEncoder(shouldEncodeElementDefault).apply {
171124
encodeSerializableValue(serializer, value)
172125
}.value
173126
}
@@ -181,7 +134,7 @@ open class FirebaseCompositeEncoder constructor(
181134
) = set(
182135
descriptor,
183136
index,
184-
FirebaseEncoder(shouldEncodeElementDefault, positiveInfinity).apply {
137+
getEncoder(shouldEncodeElementDefault).apply {
185138
encodeSerializableValue(serializer, value)
186139
}.value
187140
)
@@ -192,7 +145,7 @@ open class FirebaseCompositeEncoder constructor(
192145

193146
override fun encodeCharElement(descriptor: SerialDescriptor, index: Int, value: Char) = set(descriptor, index, value)
194147

195-
override fun encodeDoubleElement(descriptor: SerialDescriptor, index: Int, value: Double) = set(descriptor, index, encodeTimestamp(value))
148+
override fun encodeDoubleElement(descriptor: SerialDescriptor, index: Int, value: Double) = set(descriptor, index, value)
196149

197150
override fun encodeFloatElement(descriptor: SerialDescriptor, index: Int, value: Float) = set(descriptor, index, value)
198151

@@ -206,7 +159,7 @@ open class FirebaseCompositeEncoder constructor(
206159

207160
@ExperimentalSerializationApi
208161
override fun encodeInlineElement(descriptor: SerialDescriptor, index: Int): Encoder =
209-
FirebaseEncoder(shouldEncodeElementDefault, positiveInfinity)
162+
FirebaseEncoder(shouldEncodeElementDefault)
210163
}
211164

212165

0 commit comments

Comments
 (0)