tidy up event-schema ksx json stuff, and make the "empty list <-> empty object" thing contextual
This commit is contained in:
parent
678cf5504e
commit
97d0de56e7
8 changed files with 74 additions and 51 deletions
|
|
@ -6,7 +6,7 @@ plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "dev.adamko.kafkatorio"
|
group = "dev.adamko.kafkatorio"
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
|
|
||||||
val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE"))
|
val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE"))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package dev.adamko.kafkatorio.events.schema
|
package dev.adamko.kafkatorio.events.schema
|
||||||
|
|
||||||
|
import kotlinx.serialization.Contextual
|
||||||
import kotlinx.serialization.DeserializationStrategy
|
import kotlinx.serialization.DeserializationStrategy
|
||||||
import kotlinx.serialization.EncodeDefault
|
import kotlinx.serialization.EncodeDefault
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
@ -9,7 +10,7 @@ import kotlinx.serialization.json.contentOrNull
|
||||||
import kotlinx.serialization.json.jsonObject
|
import kotlinx.serialization.json.jsonObject
|
||||||
import kotlinx.serialization.json.jsonPrimitive
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
|
|
||||||
@Serializable(with = FactorioObjectDataSerializer::class)
|
@Serializable(with = FactorioObjectDataJsonSerializer::class)
|
||||||
sealed class FactorioObjectData {
|
sealed class FactorioObjectData {
|
||||||
|
|
||||||
@EncodeDefault
|
@EncodeDefault
|
||||||
|
|
@ -43,7 +44,7 @@ sealed class FactorioObjectData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object FactorioObjectDataSerializer : JsonContentPolymorphicSerializer<FactorioObjectData>(
|
object FactorioObjectDataJsonSerializer : JsonContentPolymorphicSerializer<FactorioObjectData>(
|
||||||
FactorioObjectData::class
|
FactorioObjectData::class
|
||||||
) {
|
) {
|
||||||
private val key = FactorioObjectData::objectName.name
|
private val key = FactorioObjectData::objectName.name
|
||||||
|
|
@ -58,6 +59,8 @@ object FactorioObjectDataSerializer : JsonContentPolymorphicSerializer<FactorioO
|
||||||
FactorioObjectData.ObjectName.values().firstOrNull { it.name == json }
|
FactorioObjectData.ObjectName.values().firstOrNull { it.name == json }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
requireNotNull(type) { "Unknown FactorioObjectData $key: $element" }
|
||||||
|
|
||||||
return when (type) {
|
return when (type) {
|
||||||
FactorioObjectData.ObjectName.LuaPlayer -> PlayerData.serializer()
|
FactorioObjectData.ObjectName.LuaPlayer -> PlayerData.serializer()
|
||||||
FactorioObjectData.ObjectName.LuaEntity -> EntityData.serializer()
|
FactorioObjectData.ObjectName.LuaEntity -> EntityData.serializer()
|
||||||
|
|
@ -66,8 +69,6 @@ object FactorioObjectDataSerializer : JsonContentPolymorphicSerializer<FactorioO
|
||||||
FactorioObjectData.ObjectName.LuaTile -> MapTile.serializer()
|
FactorioObjectData.ObjectName.LuaTile -> MapTile.serializer()
|
||||||
FactorioObjectData.ObjectName.LuaTiles -> MapTiles.serializer()
|
FactorioObjectData.ObjectName.LuaTiles -> MapTiles.serializer()
|
||||||
FactorioObjectData.ObjectName.ConsoleChatMessage -> ConsoleChatMessage.serializer()
|
FactorioObjectData.ObjectName.ConsoleChatMessage -> ConsoleChatMessage.serializer()
|
||||||
null ->
|
|
||||||
throw Exception("Unknown FactorioObjectData $key: '$type' ")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -75,7 +76,8 @@ object FactorioObjectDataSerializer : JsonContentPolymorphicSerializer<FactorioO
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class PlayerData(
|
data class PlayerData(
|
||||||
@Serializable(with = ListAsObjectSerializer::class)
|
// @Serializable(with = FactorioJsonListSerializer::class)
|
||||||
|
@Contextual
|
||||||
val associatedCharactersUnitNumbers: List<UInt>,
|
val associatedCharactersUnitNumbers: List<UInt>,
|
||||||
val characterUnitNumber: UInt?,
|
val characterUnitNumber: UInt?,
|
||||||
val name: String,
|
val name: String,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package dev.adamko.kafkatorio.events.schema
|
package dev.adamko.kafkatorio.events.schema
|
||||||
|
|
||||||
|
import dev.adamko.kafkatorio.events.schema.FactorioPrototype.PrototypeObjectName
|
||||||
|
import kotlinx.serialization.Contextual
|
||||||
import kotlinx.serialization.DeserializationStrategy
|
import kotlinx.serialization.DeserializationStrategy
|
||||||
import kotlinx.serialization.EncodeDefault
|
import kotlinx.serialization.EncodeDefault
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
@ -20,7 +22,7 @@ data class FactorioPrototypes(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Serializable(with = FactorioPrototypeSerializer::class)
|
@Serializable(with = FactorioPrototypeJsonSerializer::class)
|
||||||
sealed class FactorioPrototype {
|
sealed class FactorioPrototype {
|
||||||
@EncodeDefault
|
@EncodeDefault
|
||||||
abstract val prototypeObjectName: PrototypeObjectName
|
abstract val prototypeObjectName: PrototypeObjectName
|
||||||
|
|
@ -30,7 +32,8 @@ sealed class FactorioPrototype {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object FactorioPrototypeSerializer : JsonContentPolymorphicSerializer<FactorioPrototype>(
|
|
||||||
|
object FactorioPrototypeJsonSerializer : JsonContentPolymorphicSerializer<FactorioPrototype>(
|
||||||
FactorioPrototype::class
|
FactorioPrototype::class
|
||||||
) {
|
) {
|
||||||
private val key = FactorioPrototype::prototypeObjectName.name
|
private val key = FactorioPrototype::prototypeObjectName.name
|
||||||
|
|
@ -42,13 +45,13 @@ object FactorioPrototypeSerializer : JsonContentPolymorphicSerializer<FactorioPr
|
||||||
?.jsonPrimitive
|
?.jsonPrimitive
|
||||||
?.contentOrNull
|
?.contentOrNull
|
||||||
?.let { json ->
|
?.let { json ->
|
||||||
FactorioPrototype.PrototypeObjectName.values().firstOrNull { it.name == json }
|
PrototypeObjectName.values().firstOrNull { it.name == json }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
requireNotNull(type) { "Unknown FactorioPrototype ${key}: $element" }
|
||||||
|
|
||||||
return when (type) {
|
return when (type) {
|
||||||
FactorioPrototype.PrototypeObjectName.LuaTilePrototype -> MapTilePrototype.serializer()
|
PrototypeObjectName.LuaTilePrototype -> MapTilePrototype.serializer()
|
||||||
null ->
|
|
||||||
throw Exception("Unknown FactorioPrototype $key: '$type' ")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -59,7 +62,8 @@ data class MapTilePrototype(
|
||||||
val name: String,
|
val name: String,
|
||||||
val layer: UInt,
|
val layer: UInt,
|
||||||
val mapColour: Colour,
|
val mapColour: Colour,
|
||||||
@Serializable(with = FactorioJsonListSerializer::class)
|
// @Serializable(with = FactorioJsonListSerializer::class)
|
||||||
|
@Contextual
|
||||||
val collisionMasks: List<String>,
|
val collisionMasks: List<String>,
|
||||||
val order: String,
|
val order: String,
|
||||||
/** Can the tile be mined for resources? */
|
/** Can the tile be mined for resources? */
|
||||||
|
|
|
||||||
|
|
@ -7,46 +7,62 @@ import kotlinx.serialization.json.JsonArray
|
||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.JsonElement
|
||||||
import kotlinx.serialization.json.JsonObject
|
import kotlinx.serialization.json.JsonObject
|
||||||
import kotlinx.serialization.json.JsonTransformingSerializer
|
import kotlinx.serialization.json.JsonTransformingSerializer
|
||||||
import kotlinx.serialization.json.jsonArray
|
import kotlinx.serialization.json.buildJsonObject
|
||||||
import kotlinx.serialization.json.jsonObject
|
import kotlinx.serialization.modules.SerializersModule
|
||||||
|
|
||||||
val jsonMapperKafkatorio = Json {
|
val jsonMapperKafkatorio = Json {
|
||||||
prettyPrint = true
|
prettyPrint = true
|
||||||
prettyPrintIndent = " "
|
prettyPrintIndent = " "
|
||||||
// serializersModule = FactorioEvent.kxsModule
|
|
||||||
// serializersModule = KafkatorioPacket.kxsModule + FactorioEvent.kxsModule
|
serializersModule = SerializersModule {
|
||||||
// serializersModule = SerializersModule { }
|
contextual(List::class) { args -> FactorioJsonListSerializer(args[0]) }
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Factorio outputs lists as Json objects - this serializer converts an object back to a list. */
|
/**
|
||||||
// actually I'm not sure that it does - I think *empty* lists get encoded as *empty* objects
|
* Factorio outputs an *empty* list as an *empty* Json object. This serde performs the same
|
||||||
internal class ListAsObjectSerializer<T>(dataSerializer: KSerializer<T>) :
|
* conversion
|
||||||
JsonTransformingSerializer<List<T>>(ListSerializer(dataSerializer)) {
|
*/
|
||||||
|
class FactorioJsonListSerializer<T>(dataSerializer: KSerializer<T>) :
|
||||||
override fun transformDeserialize(element: JsonElement): JsonElement =
|
|
||||||
JsonArray(
|
|
||||||
element.jsonObject.values.toList()
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun transformSerialize(element: JsonElement): JsonElement =
|
|
||||||
JsonObject(
|
|
||||||
element.jsonArray.mapIndexed { index, jsonElement -> "$index" to jsonElement }.toMap()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Factorio outputs lists as Json objects - this serializer converts an object back to a list. */
|
|
||||||
// actually I'm not sure that it does - I think *empty* lists get encoded as *empty* objects
|
|
||||||
internal class FactorioJsonListSerializer<T>(dataSerializer: KSerializer<T>) :
|
|
||||||
JsonTransformingSerializer<List<T>>(ListSerializer(dataSerializer)) {
|
JsonTransformingSerializer<List<T>>(ListSerializer(dataSerializer)) {
|
||||||
|
|
||||||
override fun transformDeserialize(element: JsonElement): JsonElement {
|
override fun transformDeserialize(element: JsonElement): JsonElement {
|
||||||
return if (element is JsonObject) {
|
return when (element) {
|
||||||
JsonArray(emptyList())
|
is JsonObject -> JsonArray(emptyList())
|
||||||
} else {
|
else -> element
|
||||||
element
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformSerialize(element: JsonElement): JsonElement {
|
||||||
|
return when {
|
||||||
|
element is JsonArray && element.isEmpty() -> buildJsonObject { }
|
||||||
|
else -> element
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//internal class FactorioListSerializer<T : Any>(
|
||||||
|
// private val tSerializer: KSerializer<T>
|
||||||
|
//) : KSerializer<List<T>> {
|
||||||
|
//
|
||||||
|
// override val descriptor: SerialDescriptor get() = tSerializer.descriptor
|
||||||
|
// private val tListSerializer = ListSerializer(tSerializer)
|
||||||
|
// private val jsonTransformer = FactorioJsonListSerializer(tSerializer)
|
||||||
|
//
|
||||||
|
// override fun serialize(encoder: Encoder, value: List<T>) {
|
||||||
|
// when (encoder) {
|
||||||
|
// is JsonEncoder -> jsonTransformer.serialize(encoder, value)
|
||||||
|
// else -> tListSerializer.serialize(encoder, value)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// override fun deserialize(decoder: Decoder): List<T> {
|
||||||
|
// return when (decoder) {
|
||||||
|
// is JsonDecoder -> jsonTransformer.deserialize(decoder)
|
||||||
|
// else -> tListSerializer.deserialize(decoder)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import kotlinx.serialization.json.jsonObject
|
||||||
import kotlinx.serialization.json.jsonPrimitive
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
|
|
||||||
|
|
||||||
@Serializable(with = KafkatorioPacketSerializer::class)
|
@Serializable(with = KafkatorioPacketJsonSerializer::class)
|
||||||
sealed class KafkatorioPacket {
|
sealed class KafkatorioPacket {
|
||||||
/** Schema versioning */
|
/** Schema versioning */
|
||||||
abstract val modVersion: String
|
abstract val modVersion: String
|
||||||
|
|
@ -24,7 +24,8 @@ sealed class KafkatorioPacket {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object KafkatorioPacketSerializer : JsonContentPolymorphicSerializer<KafkatorioPacket>(
|
|
||||||
|
object KafkatorioPacketJsonSerializer : JsonContentPolymorphicSerializer<KafkatorioPacket>(
|
||||||
KafkatorioPacket::class
|
KafkatorioPacket::class
|
||||||
) {
|
) {
|
||||||
private val key = KafkatorioPacket::packetType.name
|
private val key = KafkatorioPacket::packetType.name
|
||||||
|
|
@ -39,12 +40,12 @@ object KafkatorioPacketSerializer : JsonContentPolymorphicSerializer<KafkatorioP
|
||||||
KafkatorioPacket.PacketType.values().firstOrNull { it.name == json }
|
KafkatorioPacket.PacketType.values().firstOrNull { it.name == json }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
requireNotNull(type) { "Unknown KafkatorioPacket ${key}: $element" }
|
||||||
|
|
||||||
return when (type) {
|
return when (type) {
|
||||||
KafkatorioPacket.PacketType.EVENT -> FactorioEvent.serializer()
|
KafkatorioPacket.PacketType.EVENT -> FactorioEvent.serializer()
|
||||||
KafkatorioPacket.PacketType.CONFIG -> FactorioConfigurationUpdate.serializer()
|
KafkatorioPacket.PacketType.CONFIG -> FactorioConfigurationUpdate.serializer()
|
||||||
KafkatorioPacket.PacketType.PROTOTYPES -> FactorioPrototypes.serializer()
|
KafkatorioPacket.PacketType.PROTOTYPES -> FactorioPrototypes.serializer()
|
||||||
null ->
|
|
||||||
throw Exception("Unknown KafkatorioPacket ${key}: '$type' ")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# Do not edit manually. This file was created with task 'dockerEnv'
|
# Do not edit manually. This file was created with task 'dockerEnv'
|
||||||
COMPOSE_PROJECT_NAME=kafkatorio
|
COMPOSE_PROJECT_NAME=kafkatorio
|
||||||
FACTORIO_VERSION=1.1.53
|
FACTORIO_VERSION=1.1.53
|
||||||
KAFKATORIO_VERSION=0.2.6
|
KAFKATORIO_VERSION=0.2.7
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
# Do not edit manually. This file was created with task 'dockerEnv'
|
# Do not edit manually. This file was created with task 'dockerEnv'
|
||||||
COMPOSE_PROJECT_NAME=kafkatorio
|
COMPOSE_PROJECT_NAME=kafkatorio
|
||||||
KAFKATORIO_VERSION=0.2.6
|
KAFKATORIO_VERSION=0.2.7
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
# Do not edit manually. This file was created with task 'dockerEnv'
|
# Do not edit manually. This file was created with task 'dockerEnv'
|
||||||
COMPOSE_PROJECT_NAME=kafkatorio
|
COMPOSE_PROJECT_NAME=kafkatorio
|
||||||
KAFKATORIO_VERSION=0.2.6
|
KAFKATORIO_VERSION=0.2.7
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue