Question: can you have a value class that serializes like a data class? I got bit by making a value class over a single field JSON payload.
chiroptical
04/30/2023, 9:54 PM
Basically fighting with UUIDs serialization to/from json and to the database. ignore this. I am confusing two of my issues ha
e
Emil Kantis
04/30/2023, 10:03 PM
I think you'd need a
JsonTransformingSerializer
for that.
Copy code
inline fun <reified T : Any> objectWrappingSerializer(fieldName: String) = object : JsonTransformingSerializer<T>(serializer()) {
override fun transformSerialize(element: JsonElement): JsonElement {
return buildJsonObject {
put(fieldName, element)
}
}
override fun transformDeserialize(element: JsonElement): JsonElement {
return element.jsonObject[fieldName]!!
}
}
create your serializer like:
Copy code
object MyValueClassSerializer :KSerializer<MyValueClass> by objectWrappingSerializer("fieldName")
@Serializable(with = MyValueClassSerializer::class)
value class MyValueClass(..)
c
chr
05/03/2023, 2:55 AM
☝️ this doesn't seem to work for me, since it looks like the
serializer()
we're trying to reference in the argument is the serializer that we're trying to construct in
objectWrappingSerializer(...)
e
Emil Kantis
05/03/2023, 5:04 PM
Sorry, you're right. The usage is wrong but the
objectWrpapingSerializer
works..
Emil Kantis
05/03/2023, 5:04 PM
Copy code
@Serializable
@JvmInline
private value class PersonName(val value: String)
object PersonNameSerializer : KSerializer<PersonName> by objectWrappingSerializer("name")
class ObjectWrappingSerializerTest : FreeSpec(
{
"Serializes correctly" {
Json.encodeToString(PersonNameSerializer, PersonName("John")) shouldEqualJson """{"name":"John"}"""
}
},
)
Passes now that we're creating the auto-generated serializer first