
com.lightningkite.lightningdb.ModificationSerialization.kt Maven / Gradle / Ivy
@file:OptIn(ExperimentalSerializationApi::class, InternalSerializationApi::class)
package com.lightningkite.lightningdb
import com.lightningkite.khrysalis.IsEquatable
import com.lightningkite.khrysalis.fatalError
import kotlinx.serialization.*
import kotlin.reflect.KClass
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.builtins.MapSerializer
import kotlinx.serialization.builtins.SetSerializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.*
import kotlinx.serialization.internal.GeneratedSerializer
import java.util.*
import kotlin.reflect.KProperty1
import kotlin.reflect.full.allSupertypes
import kotlin.reflect.jvm.jvmErasure
private val serializers = HashMap, MySealedClassSerializerInterface<*>>()
private val numberKinds = setOf(
PrimitiveKind.BYTE,
PrimitiveKind.INT,
PrimitiveKind.SHORT,
PrimitiveKind.LONG,
PrimitiveKind.FLOAT,
PrimitiveKind.DOUBLE
)
@Suppress("UNCHECKED_CAST")
private fun getMod(inner: KSerializer): MySealedClassSerializerInterface> =
serializers.getOrPut(inner) {
MySealedClassSerializer(
"com.lightningkite.lightningdb.Modification",
Modification::class as KClass>,
{
val map = LinkedHashMap>>()
fun register(serializer: KSerializer>) {
map[serializer.descriptor.serialName] = (serializer as KSerializer>)
}
register(Modification.Chain.serializer(inner))
if (inner.descriptor.isNullable) {
register(Modification.IfNotNull.serializer(inner))
}
register(Modification.Assign.serializer(inner))
// if (inner.descriptor.kind is PrimitiveKind) {
register(Modification.CoerceAtMost.serializer(inner))
register(Modification.CoerceAtLeast.serializer(inner))
// }
if (inner.descriptor.kind in numberKinds) {
register(Modification.Increment.serializer(inner))
register(Modification.Multiply.serializer(inner))
}
if (inner == String.serializer()) register(Modification.AppendString.serializer())
if (inner.descriptor.kind == StructureKind.LIST) {
inner.listElement()?.let { element ->
register(Modification.SetAppend.serializer(element))
register(Modification.SetRemove.serializer(element))
register(Modification.SetRemoveInstances.serializer(element))
register(Modification.SetDropFirst.serializer(element))
register(Modification.SetDropLast.serializer(element))
register(Modification.SetPerElement.serializer(element))
register(Modification.ListAppend.serializer(element))
register(Modification.ListRemove.serializer(element))
register(Modification.ListRemoveInstances.serializer(element))
register(Modification.ListDropFirst.serializer(element))
register(Modification.ListDropLast.serializer(element))
register(Modification.ListPerElement.serializer(element))
}
}
if (inner.descriptor.kind == StructureKind.MAP) {
inner.mapValueElement()?.let { element ->
register(Modification.Combine.serializer(element))
register(Modification.ModifyByKey.serializer(element))
register(Modification.RemoveKeys.serializer(element))
}
}
if (inner is GeneratedSerializer<*> && inner.descriptor.kind == StructureKind.CLASS && inner !is MySealedClassSerializerInterface) {
val childSerializers = inner.childSerializers()
val fields = inner.attemptGrabFields()
for (index in 0 until inner.descriptor.elementsCount) {
val name = inner.descriptor.getElementName(index)
val prop = fields[name]!!
register(
OnFieldSerializer2(
prop as KProperty1,
Modification.serializer(childSerializers[index]) as KSerializer>
)
)
}
}
if (inner.descriptor.isNullable) {
inner.nullElement()?.let { element ->
register(Modification.IfNotNull.serializer(element))
}
}
map
},
annotations = Modification::class.annotations,
alternateReadNames = mapOf(
"AppendList" to "ListAppend",
"AppendSet" to "SetAppend",
"Remove" to "ListRemove",
"RemoveInstances" to "ListRemoveInstances",
"DropFirst" to "ListDropFirst",
"DropLast" to "ListDropLast",
"PerElement" to "ListPerElement",
)
) {
when (it) {
is Modification.Chain -> "Chain"
is Modification.IfNotNull<*> -> "IfNotNull"
is Modification.Assign -> "Assign"
is Modification.CoerceAtMost -> "CoerceAtMost"
is Modification.CoerceAtLeast -> "CoerceAtLeast"
is Modification.Increment -> "Increment"
is Modification.Multiply -> "Multiply"
is Modification.AppendString -> "AppendString"
is Modification.ListAppend<*> -> "ListAppend"
is Modification.ListRemove<*> -> "ListRemove"
is Modification.ListRemoveInstances<*> -> "ListRemoveInstances"
is Modification.ListDropFirst<*> -> "ListDropFirst"
is Modification.ListDropLast<*> -> "ListDropLast"
is Modification.ListPerElement<*> -> "ListPerElement"
is Modification.SetAppend<*> -> "SetAppend"
is Modification.SetRemove<*> -> "SetRemove"
is Modification.SetRemoveInstances<*> -> "SetRemoveInstances"
is Modification.SetDropFirst<*> -> "SetDropFirst"
is Modification.SetDropLast<*> -> "SetDropLast"
is Modification.SetPerElement<*> -> "SetPerElement"
is Modification.Combine<*> -> "Combine"
is Modification.ModifyByKey<*> -> "ModifyByKey"
is Modification.RemoveKeys<*> -> "RemoveKeys"
is Modification.OnField<*, *> -> it.key.name
else -> fatalError()
}
}
} as MySealedClassSerializerInterface>
class ModificationSerializer(val inner: KSerializer) :
MySealedClassSerializerInterface> by getMod(inner)
class OnFieldSerializer2(
val field: KProperty1,
val conditionSerializer: KSerializer>
) : WrappingSerializer, Modification>(field.name) {
override fun getDeferred(): KSerializer> = conditionSerializer
override fun inner(it: Modification.OnField): Modification = it.modification
override fun outer(it: Modification): Modification.OnField = Modification.OnField(field, it)
}
class ModificationChainSerializer(val inner: KSerializer) :
WrappingSerializer, List>>("Chain") {
override fun getDeferred(): KSerializer>> = ListSerializer(Modification.serializer(inner))
override fun inner(it: Modification.Chain): List> = it.modifications
override fun outer(it: List>): Modification.Chain = Modification.Chain(it)
}
class ModificationIfNotNullSerializer(val inner: KSerializer) :
WrappingSerializer, Modification>("IfNotNull") {
override fun getDeferred(): KSerializer> = Modification.serializer(inner)
override fun inner(it: Modification.IfNotNull): Modification = it.modification
override fun outer(it: Modification): Modification.IfNotNull = Modification.IfNotNull(it)
}
class ModificationAssignSerializer(val inner: KSerializer) :
WrappingSerializer, T>("Assign") {
override fun getDeferred(): KSerializer = inner
override fun inner(it: Modification.Assign): T = it.value
override fun outer(it: T): Modification.Assign = Modification.Assign(it)
}
class ModificationCoerceAtMostSerializer>(val inner: KSerializer) :
WrappingSerializer, T>("CoerceAtMost") {
override fun getDeferred(): KSerializer = inner
override fun inner(it: Modification.CoerceAtMost): T = it.value
override fun outer(it: T): Modification.CoerceAtMost = Modification.CoerceAtMost(it)
}
class ModificationCoerceAtLeastSerializer>(val inner: KSerializer) :
WrappingSerializer, T>("CoerceAtLeast") {
override fun getDeferred(): KSerializer = inner
override fun inner(it: Modification.CoerceAtLeast): T = it.value
override fun outer(it: T): Modification.CoerceAtLeast = Modification.CoerceAtLeast(it)
}
class ModificationIncrementSerializer(val inner: KSerializer) :
WrappingSerializer, T>("Increment") {
override fun getDeferred(): KSerializer = inner
override fun inner(it: Modification.Increment): T = it.by
override fun outer(it: T): Modification.Increment = Modification.Increment(it)
}
class ModificationMultiplySerializer(val inner: KSerializer) :
WrappingSerializer, T>("Multiply") {
override fun getDeferred(): KSerializer = inner
override fun inner(it: Modification.Multiply): T = it.by
override fun outer(it: T): Modification.Multiply = Modification.Multiply(it)
}
object ModificationAppendStringSerializer : WrappingSerializer("AppendString") {
override fun getDeferred(): KSerializer = String.serializer()
override fun inner(it: Modification.AppendString): String = it.value
override fun outer(it: String): Modification.AppendString = Modification.AppendString(it)
}
class ModificationListAppendSerializer(val inner: KSerializer) :
WrappingSerializer, List>("ListAppend") {
override fun getDeferred() = ListSerializer(inner)
override fun inner(it: Modification.ListAppend): List = it.items
override fun outer(it: List): Modification.ListAppend = Modification.ListAppend(it)
}
class ModificationSetAppendSerializer(val inner: KSerializer) :
WrappingSerializer, Set>("SetAppend") {
override fun getDeferred() = SetSerializer(inner)
override fun inner(it: Modification.SetAppend): Set = it.items
override fun outer(it: Set): Modification.SetAppend = Modification.SetAppend(it)
}
class ModificationListRemoveSerializer(val inner: KSerializer) :
WrappingSerializer, Condition>("ListRemove") {
override fun getDeferred() = Condition.serializer(inner)
override fun inner(it: Modification.ListRemove): Condition = it.condition
override fun outer(it: Condition): Modification.ListRemove = Modification.ListRemove(it)
}
class ModificationSetRemoveSerializer(val inner: KSerializer) :
WrappingSerializer, Condition>("SetRemove") {
override fun getDeferred() = Condition.serializer(inner)
override fun inner(it: Modification.SetRemove): Condition = it.condition
override fun outer(it: Condition): Modification.SetRemove = Modification.SetRemove(it)
}
class ModificationListRemoveInstancesSerializer(val inner: KSerializer) :
WrappingSerializer, List>("ListRemoveInstances") {
override fun getDeferred() = ListSerializer(inner)
override fun inner(it: Modification.ListRemoveInstances): List = it.items
override fun outer(it: List): Modification.ListRemoveInstances = Modification.ListRemoveInstances(it)
}
class ModificationSetRemoveInstancesSerializer(val inner: KSerializer) :
WrappingSerializer, Set>("SetRemoveInstances") {
override fun getDeferred() = SetSerializer(inner)
override fun inner(it: Modification.SetRemoveInstances): Set = it.items
override fun outer(it: Set): Modification.SetRemoveInstances = Modification.SetRemoveInstances(it)
}
class ModificationCombineSerializer(val inner: KSerializer) :
WrappingSerializer, Map>("Combine") {
override fun getDeferred(): KSerializer
© 2015 - 2025 Weber Informatics LLC | Privacy Policy