
commonMain.maryk.core.models.ReferenceValuePairsDataModel.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core-jvm Show documentation
Show all versions of core-jvm Show documentation
Maryk is a Kotlin Multiplatform library which helps you to store, query and send data in a structured way over multiple platforms. The data store stores any value with a version, so it is possible to request only the changed data or live listen for updates.
The newest version!
package maryk.core.models
import maryk.core.exceptions.SerializationException
import maryk.core.models.serializers.ObjectDataModelSerializer
import maryk.core.properties.definitions.EmbeddedObjectDefinition
import maryk.core.properties.definitions.list
import maryk.core.properties.definitions.wrapper.IsDefinitionWrapper
import maryk.core.query.DefinedByReference
import maryk.core.query.RequestContext
import maryk.core.values.ObjectValues
import maryk.json.IllegalJsonOperation
import maryk.json.IsJsonLikeReader
import maryk.json.IsJsonLikeWriter
import maryk.json.JsonToken
import maryk.lib.exceptions.ParseException
/**
* Class for DataModels which contains a list of only reference pairs of type [R]
* Contains specific Serializer overrides to create a nicer looking output.
*/
abstract class ReferenceValuePairsDataModel, R: DefinedByReference<*>, T : Any, TO : Any>(
pairGetter: (DO) -> List,
val pairModel: ReferenceValuePairDataModel>,
): TypedObjectDataModel() {
val referenceValuePairs by list(
index = 1u,
getter = pairGetter,
valueDefinition = EmbeddedObjectDefinition(
dataModel = { pairModel }
)
)
@Suppress("UNCHECKED_CAST", "LeakingThis")
override val Serializer = object: ObjectDataModelSerializer(this as DM) {
override fun writeJson(
values: ObjectValues,
writer: IsJsonLikeWriter,
context: RequestContext?
) {
val referenceTypePairs = values { referenceValuePairs } ?: throw ParseException("ranges was not set on Range")
writer.writeJsonTypePairs(referenceTypePairs, context)
}
override fun writeObjectAsJson(
obj: DO,
writer: IsJsonLikeWriter,
context: RequestContext?,
skip: List>?
) {
@Suppress("UNCHECKED_CAST")
val pairs = model[1u]?.getter?.invoke(obj) as? List
?: throw SerializationException("No pairs defined on $obj")
writer.writeJsonTypePairs(pairs, context)
}
private fun IsJsonLikeWriter.writeJsonTypePairs(
referencePairs: List,
context: RequestContext?
) {
writeStartObject()
for (it in referencePairs) {
writeFieldName(
pairModel.reference.definition.asString(it.reference)
)
pairModel.reference.capture(context, it.reference)
pairModel.value.writeJsonValue(
pairModel.value.getPropertyAndSerialize(it, context)
?: throw SerializationException("No pair value defined on $it"),
this,
context
)
}
writeEndObject()
}
override fun readJson(reader: IsJsonLikeReader, context: RequestContext?): ObjectValues {
if (reader.currentToken == JsonToken.StartDocument) {
reader.nextToken()
}
if (reader.currentToken !is JsonToken.StartObject) {
throw IllegalJsonOperation("Expected object at start of JSON")
}
val listOfTypePairs = mutableListOf()
reader.nextToken()
walker@ do {
val token = reader.currentToken
when (token) {
is JsonToken.FieldName -> {
val refName = token.value ?: throw ParseException("Empty field name not allowed in JSON")
val reference = pairModel.reference.definition.fromString(refName, context)
pairModel.reference.capture(context, reference)
reader.nextToken()
@Suppress("UNCHECKED_CAST")
val value = pairModel.value.readJson(reader, context) as TO?
listOfTypePairs.add(
model.pairModel.values {
mapNonNulls(
[email protected] with reference,
[email protected] with value
)
}.toDataObject()
)
}
else -> break@walker
}
reader.nextToken()
} while (token !is JsonToken.Stopped)
return model.values(context) {
mapNonNulls(
model.referenceValuePairs withSerializable listOfTypePairs
)
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy