Ayfri
02/02/2023, 10:37 AMdata class Advancement(val name: String, val done: Boolean = false, val criteria: Map<String, Boolean> = mapOf())
As a map with advancements name as keys and done
as value if criteria
is empty, else as the map itself (totally ignoring done
) ?Adam S
02/02/2023, 11:10 AMdone
was a property of the class, and was annotated with @EncodeDefault
?
@Serializable
data class Advancement(
val name: String,
val criteria: Map<String, Boolean> = mapOf()
) {
@OptIn(ExperimentalSerializationApi::class)
@EncodeDefault
val done: Boolean get() = criteria.isEmpty()
}
if criteria
is empty, then it matches the default value, so shouldn’t be encoded. Whereas done
will always be encoded, which doesn’t quite match your criteria, but I think it’s close enough. Anything more could be quite complicated!Ayfri
02/02/2023, 1:02 PMdone
can also be changed explicitlyAdam S
02/02/2023, 3:05 PMdone
is set to false
and the map isn’t empty?Ayfri
02/02/2023, 3:08 PMAdam S
02/02/2023, 3:13 PMdone
is set as true
?Ayfri
02/02/2023, 3:16 PMAdam S
02/02/2023, 3:16 PMAyfri
02/02/2023, 3:17 PMAdam S
02/02/2023, 3:17 PMAyfri
02/02/2023, 3:19 PM"minecraft:my_advancement": true
Or this :
"minecraft:my_advancement": {
"condition1": false,
"condition2": true
}
Adam S
02/02/2023, 3:19 PMJsonTransformingSerializer
https://github.com/Kotlin/kotlinx.serialization/blob/v1.4.1/docs/json.md#json-transformationsAyfri
02/02/2023, 3:20 PMAdam S
02/02/2023, 3:20 PMAyfri
02/02/2023, 3:21 PMAdam S
02/02/2023, 3:27 PM@Serializable
sealed interface Advancement {
val name: String
@Serializable
data class Simple(
override val name: String,
val value: Boolean,
) : Advancement
@Serializable
data class Complex(
override val name: String,
val value: Map<String, Boolean>,
) : Advancement
}
{ name: "some-achievement", value: true, type: "Simple" }
And if you’re decoding, then type
won’t be present, and so KxS will fail
To overcome that, you need a custom serializer, and that’s what JsonContentPolymorphicSerializer
is for https://github.com/Kotlin/kotlinx.serialization/blob/v1.4.1/docs/json.md#content-based-polymorphic-deserializationAyfri
02/02/2023, 3:31 PMBen Woodworth
02/04/2023, 5:00 AMobject AdvancementSerializer : SerializationStrategy<Advancement> {
private val mapSerializer = MapSerializer(String.serializer(), Boolean.serializer())
override val descriptor: SerialDescriptor =
SerialDescriptor("my.package.Advancement", mapSerializer.descriptor)
override fun serialize(encoder: Encoder, value: Advancement) {
val map = if (value.criteria.isEmpty()) {
mapOf(value.name to value.done)
} else {
value.criteria
}
encoder.encodeSerializableValue(mapSerializer, map)
}
}
Ayfri
02/05/2023, 12:34 PMBen Woodworth
02/05/2023, 3:43 PM@Serializable
doesn't accept SerializationStrategy, but you can change my serializer to implement KSerializer and throw an error when deserializingAyfri
02/05/2023, 8:19 PM