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

commonMain.ch.softappeal.yass2.serialize.binary.BinarySerializerMeta.kt Maven / Gradle / Ivy

There is a newer version: 5.0.0
Show newest version
package ch.softappeal.yass2.serialize.binary

import kotlin.reflect.*

internal enum class MKind { WithId, NoIdRequired, NoIdOptional }

internal class MProperty(val property: KProperty1, val kind: MKind, val encoderId: Int = -1) {
    fun mutableProperty() = property as KMutableProperty1

    fun write(writer: EncoderWriter, value: Any?) = when (kind) {
        MKind.WithId -> writer.writeWithId(value)
        MKind.NoIdRequired -> writer.writeNoIdRequired(encoderId, value!!)
        MKind.NoIdOptional -> writer.writeNoIdOptional(encoderId, value)
    }

    fun read(reader: EncoderReader): Any? = when (kind) {
        MKind.WithId -> reader.readWithId()
        MKind.NoIdRequired -> reader.readNoIdRequired(encoderId)
        MKind.NoIdOptional -> reader.readNoIdOptional(encoderId)
    }
}

internal fun KClass<*>.mProperty(
    property: KProperty1,
    baseEncoderTypes: List>, concreteClasses: List>,
    optional: Boolean, isStrictSubclassOf: KClass<*>.(base: KClass<*>) -> Boolean
): MProperty {
    val kind = if (optional) MKind.NoIdOptional else MKind.NoIdRequired
    return if (this == List::class) MProperty(property, kind, ListEncoderId.id) else {
        val baseEncoder = baseEncoderTypes.indexOfFirst { it == this }
        if (baseEncoder >= 0) MProperty(property, kind, baseEncoder + FirstEncoderId) else {
            val concreteClass = concreteClasses.indexOfFirst { it == this }
            if (concreteClass >= 0 && !concreteClasses.any { it.isStrictSubclassOf(concreteClasses[concreteClass]) })
                MProperty(property, kind, concreteClass + baseEncoderTypes.size + FirstEncoderId)
            else
                MProperty(property, MKind.WithId)
        }
    }
}

internal class MClass(klass: KClass<*>, val properties: List, parameterNames: List) {
    val parameterIndices: List
    val varIndices: List

    init {
        parameterIndices = mutableListOf()
        varIndices = mutableListOf()
        parameterNames.forEach { parameter ->
            val property = properties.map { it.property.name }.indexOf(parameter)
            require(property >= 0) { "primary constructor parameter '$parameter' of '$klass' is not a property" }
            parameterIndices.add(property)
        }
        properties.withIndex().forEach { (index, property) ->
            val parameter = parameterNames.indexOf(property.property.name)
            if (parameter < 0) {
                try {
                    property.mutableProperty()
                } catch (e: Exception) {
                    throw IllegalArgumentException("body property '${property.property.name}' of '$klass' is not 'var'")
                }
                varIndices.add(index)
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy