Might be a strange question but how do you write a...
# serialization
g
Might be a strange question but how do you write a serializer for
kotlin.Result
class? Let say I want to write a custom call adapter for Retrofit that wraps all my requests in
Result
class. Right now serialization converter is failing with
Can't locate argument-less serializer for class kotlin.Result
which sounds reasonable. How would one workaround this situation?
s
Seems like asking for trouble serializing its
Throwable
no ?
g
I don't expect serialization to happen at all, I can even leave it not implemented. The only reason it's an issue is that my requests return
Result<T>
now, where
T
is an actual object to deserialize from json and
Result
is something that kotlin serialization is not aware of. As you can imagine, it's one way.
n
so you want a Result.Success<T> to serialize like a T ?
g
you can say that, yes. Although, this path should never be called, I can even throw
NotImplemented
exception or something.
n
Copy code
val <T> T.result: KSerializer<Result<T>> = ResultSerializer<T>(this)
for the shorthand
that way the
ResultSerializer
has the child serializer and can call it
g
Not sure where I'm supposed to put it. As you can imagine, I don't controll deserialization manually, it happes inside of Retrofit. So, by the time the call is performed, the Result Serializer is expected to be registered somewhere...
n
you pass retrofit some sort of Json object right ?
anyways this is the Serializer i would use.. not sure if it will work..
Copy code
class ResultSerializer<T: Any>(val childSerializer: KSerializer<Result<T>>) : KSerializer<Result<T>> {
    override val descriptor: SerialDescriptor = SerialClassDescImpl(Result::class.simpleName!!)
    override fun deserialize(decoder: Decoder): Result<T> {
        TODO()
    }
    override fun serialize(encoder: Encoder, obj: Result<T>) {
        encoder.encodeSerializableValue(childSerializer,obj)
    }
}
g
well, somewhere internally that's what is happening, yes. But I don't pass anything, it's already abstracted for the user. All you have to do is
fun foo(): Bar
where
Bar
must be serializable. And now it's
fun foo(): Result<Bar>
.
n
you register it to use kotlinx-serialization somehow though ?
otherwise does theu ser have no control over the Json options ?
g
yep
Copy code
.addConverterFactory(Json.asConverterFactory(MediaType.get("application/json")))
i think you can use Json() too there
and install default modules or whatever they are called in there
otherwise ping the author i guess
that is what kotlinx-serialization should use to look up the serializer for Result .. not sure how to register it in a way that the retrofit adapter supports