axeon
11/06/2024, 12:47 PMdata
directly into the root of the Response
object?
@Serializable
data class Response<T>(
val data: T,
val field2: String,
val field3: Int,
)
// so that
@Serializable
data class Data(
val field1: String,
)
// results in:
{
field1: string,
field2: string,
field3: number
}
glureau
11/06/2024, 12:55 PMvalue class
for your "Data"?axeon
11/06/2024, 12:56 PMData
is simply an example, the actual classes used for T are fairly complexglureau
11/06/2024, 12:57 PMaxeon
11/06/2024, 12:59 PMkotlinx.serialization
beyond simple use cases. how would i setup that deserialization logic in the custom serializer?axeon
11/06/2024, 1:00 PMaxeon
11/06/2024, 1:02 PMglureau
11/06/2024, 1:08 PMclass ResponseSerializer(generatedSerializer: KSerializer<T>) : JsonTransformingSerializer<Response<T>>(serializer) {
private val field2Name = "field2"
private val field3Name = "field3"
override val descriptor: SerialDescriptor = buildClassSerialDescriptor {
element<String>(field2Name)
element<String>(field3Name)
val fieldDescriptorIndex = serializer.descriptor.getElementIndex(fieldName)
val fieldDescriptor = serializer.descriptor.getElementDescriptor(fieldDescriptorIndex)
fieldDescriptor.elementNames.forEachIndexed { index, name ->
val content = fieldDescriptor.getElementDescriptor(index)
element(
elementName = name,
annotations = content.annotations,
descriptor = content,
isOptional = content.isNullable
)
}
}
override fun transformSerialize(element: JsonElement): JsonElement {
val contentJson = requireNotNull(element.jsonObject[fieldName]).jsonObject
val field2 = requireNotNull(element.jsonObject[field2Name]).jsonPrimitive.content
val field3 = requireNotNull(element.jsonObject[field3Name]).jsonPrimitive.content
val updated = buildMap {
put(rootUUIDFieldName, JsonPrimitive(rootUUID))
put(playheadFieldName, JsonPrimitive(playhead))
putAll(contentJson)
}
return super.transformSerialize(JsonObject(updated))
}
override fun transformDeserialize(element: JsonElement): JsonElement {
val field2 = requireNotNull(element.jsonObject[field2Name]).jsonPrimitive.content
val field3 = requireNotNull(element.jsonObject[field3Name]).jsonPrimitive.content
val updated = element.jsonObject - rootUUIDFieldName
return super.transformDeserialize(
JsonObject(
mapOf(
field2Name to JsonPrimitive(rootUUID),
field3Name to JsonPrimitive(playhead),
fieldName to JsonObject(updated),
)
)
)
}
}
glureau
11/06/2024, 1:10 PMglureau
11/06/2024, 1:11 PMaxeon
11/06/2024, 1:40 PMaxeon
11/06/2024, 2:29 PMaxeon
11/06/2024, 2:32 PM@Serializable(ResponseSerializer::class)
sealed class Response<out T> {
data class Ok<out T>(val data: T, val otherFields: String) : Response<T>()
data class Error(val error: Err) : Response<Nothing>()
}
axeon
11/06/2024, 2:33 PM