I offer to include @Flat (or @Flatten, for example) annotation which will be used in cases when value object of field must be included directly into parent object.
@Serializable
data class Parent(
val stringField: String = "stringValue",
@Flat
val flatField: Child = Child()
)
@Serializable
class Child {
val childString: String = "childValue"
}
fun main(args: Array<String>) {
println(JSON.stringify(Parent.serializer(), Parent()))
}
Will give result:
{"stringField":"stringValue","childString":"childValue"}
Here I see a few problems:
String and other primitives must be resolved like common fields (with their keys) or those fields must lead to exception like IllegalArgumentExceptionSo, next code will give the same effect:
@Serializable(ParentFlatChildSerializer::class)
data class Parent(
val stringField: String = "stringValue",
val flatField: Child = Child()
)
@Serializable
class Child {
@Optional
val flatFieldValue: String = "flatFieldValue"
}
@Serializer(Parent::class)
object ParentFlatChildSerializer : KSerializer<Parent> {
override fun serialize(output: Encoder, obj: Parent) {
output.beginStructure(
descriptor
).apply {
encodeStringElement(
descriptor, 0, obj.stringField
)
encodeStringElement(Child.serializer().descriptor, 0, obj.flatField.flatFieldValue)
}.endStructure(
descriptor
)
}
}
fun main(args: Array<String>) {
println(JSON.stringify(ParentFlatChildSerializer, Parent()))
}
But it is much longer and is not useful to write serializer like this for each object/class in projects.
Any information about this? Is there some workaround, or will it be implemented in near future?