Improve documentation for buildClassSerialDescriptor
What is your use-case and why do you need this feature?
I'm trying to build a custom KSerializer for a class that has a list property:
@Serializable(with = ListingSerializer::class)
data class Listing(
val after: String?,
val before: String?,
val posts: List<Post>
)
object ListingSerializer: KSerializer<Listing> {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("Listing") {
element<String>("after")
element<String>("before")
// what to put in here ??
}
override fun serialize(encoder: Encoder, value: Listing) { ... }
override fun deserialize(decoder: Decoder): Listing { ... }
}
The hand-written composite serializer section for the serializers guide says to use buildClassSerialDescriptor. However, it does not say that to use when using collections. The guide for json also has a few snippets where buildClassSerialDescriptor is used, but not for collections.
Checking the documentation for buildClassSerialDescriptor itself, I'm quite confused because it doesn't show buildClassSerialDescriptor but instead SerialDescriptor. Am I supposed to use SerialDescriptor instead? That's not what it's in the guide, so I'm a bit confused.
Inside it are these three lines:
element<Long>("_longField") // longField is named as _longField
element("stringField", listDescriptor<String>())
element("nullableInt", descriptor<Int>().nullable)
This seems similar to what the guide says about buildClassSerialDescriptor, but calling them inside it does not work for listDescriptor or descriptor<Int>().nullable.
In the documentation for buildClassSerialDescriptor, there also an example for generic classes. In it, there's listSerialDescriptor which is what I used for my case.
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("Listing") {
element<String>("after")
element<String>("before")
// is this better?
element("things", listSerialDescriptor(Post.serializer().descriptor))
// or is this better?
element("things", listSerialDescriptor<Post>())
}
My code works great! Although it says it's "experimental" so I'm not sure if it's the recommended way to do it.
Describe the solution you'd like
I think it would be pretty cool if the guide had an example for a descriptor using a collection, or if the documentation for buildClassSerialDescriptor looked a bit more like how it's used in the guide (and with a collection example).
Environment
- Kotlin version: 1.4.32
- Library version: 1.4.32
- Kotlin platforms: JVM
- Gradle version: 6.7
- IDE version: 2021.1
- Other relevant context: Java 11, Linux 5.10
Run into the same problem. Outdated doc is not very optimal... Maybe at least add a warning that this section is outdated?
SerialDescriptor in the doc of buildClassSerialDescriptor is merely an error, there's no such function that would accept lambda with builder. Sorry for that.
Regarding ListSerializer(Post.serializer().descriptor) — it is equal to the listSerialDescriptor. listSerialDescriptor is just a shorthand and we're not sure it is needed at all, that's why it experimental