All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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> = MapSerializer(serializer(), inner)
    override fun inner(it: Modification.Combine): Map = it.map
    override fun outer(it: Map): Modification.Combine = Modification.Combine(it)
}

class ModificationModifyByKeySerializer(val inner: KSerializer) :
    WrappingSerializer, Map>>("ModifyByKey") {
    override fun getDeferred(): KSerializer>> =
        MapSerializer(serializer(), Modification.serializer(inner))

    override fun inner(it: Modification.ModifyByKey): Map> = it.map
    override fun outer(it: Map>): Modification.ModifyByKey = Modification.ModifyByKey(it)
}

class ModificationRemoveKeysSerializer(val inner: KSerializer) :
    WrappingSerializer, Set>("RemoveKeys") {
    override fun getDeferred(): KSerializer> = SetSerializer(serializer())
    override fun inner(it: Modification.RemoveKeys): Set = it.fields
    override fun outer(it: Set): Modification.RemoveKeys = Modification.RemoveKeys(it)
}

class ModificationListDropFirstSerializer(val inner: KSerializer) :
    WrappingSerializer, Boolean>("ListDropFirst") {
    override fun getDeferred(): KSerializer = Boolean.serializer()
    override fun inner(it: Modification.ListDropFirst): Boolean = true
    override fun outer(it: Boolean): Modification.ListDropFirst = Modification.ListDropFirst()
}

class ModificationSetDropFirstSerializer(val inner: KSerializer) :
    WrappingSerializer, Boolean>("SetDropFirst") {
    override fun getDeferred(): KSerializer = Boolean.serializer()
    override fun inner(it: Modification.SetDropFirst): Boolean = true
    override fun outer(it: Boolean): Modification.SetDropFirst = Modification.SetDropFirst()
}

class ModificationListDropLastSerializer(val inner: KSerializer) :
    WrappingSerializer, Boolean>("ListDropLast") {
    override fun getDeferred(): KSerializer = Boolean.serializer()
    override fun inner(it: Modification.ListDropLast): Boolean = true
    override fun outer(it: Boolean): Modification.ListDropLast = Modification.ListDropLast()
}

class ModificationSetDropLastSerializer(val inner: KSerializer) :
    WrappingSerializer, Boolean>("SetDropLast") {
    override fun getDeferred(): KSerializer = Boolean.serializer()
    override fun inner(it: Modification.SetDropLast): Boolean = true
    override fun outer(it: Boolean): Modification.SetDropLast = Modification.SetDropLast()
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy