I'm trying to write a wrapper class (a port and an adapter if you will) for a JsonHandler so that I can easily swap out my dependency if needed.
Here is what I'd like to have for my port:
interface JsonHandler {
fun <Type : Any> serialize(instance: Type): String
fun <Type : Any> deserialize(json: String, type: Class<Type>): Type
}
The issue that I'm facing now is that I want to use Moshi for this, so this is how I was trying to write my adapter:
class MoshiJsonHandler(private val moshi: Moshi) : JsonHandler {
override fun <T : Any> serialize(instance: T): String {
return moshi.adapter(instance::class.java).toJson(instance)
}
//deserialize ommited for brevity
However that gives me an error:
Type mismatch: inferred type is T#1 (type parameter of MoshiJsonHandler.serialize) but Nothing? was expected. Projected type JsonAdapter<out T#1!>! restricts use of public final fun toJson(p0: T#2 (type parameter of com.squareup.moshi.JsonAdapter)?): String! defined in com.squareup.moshi.JsonAdapter
I'm not great with generics, but I vaguely understand that asking for instance::class.java where instance is of type T is not something that Kotlin/Java likes. So I ended up with this changed signature and implementation:
class MoshiJsonHandler(private val moshi: Moshi) : JsonHandler {
override fun <T : Any> serialize(instance: T, type: Class<T>): String {
return moshi.adapter(type).toJson(instance)
}
}
That's far from ideal though, because if I switch to gson then I'll have this redundant type argument in my serialize() method. Is there a way to fix my first attempt and not have to provide an extra Class<T> parameter?