'Moshi : Generic Json converter for Room entity
I am trying to create a generic JSON parser String to Object with Moshi but I am not sure if I am doing it right as I am stuck in a scenario which needs to deal with List.
The idea of this interface is it can be implemented either with a Gson or Moshi parser
interface JsonParser {
    fun <T> fromJson(jsonString: String, type: Class<T>): T?
    fun <T> toJson(obj: T, type: Class<T>): String?
}
Sample Moshi parser
class MoshiParser(private val moshi: Moshi) : JsonParser {
    override fun <T> fromJson(jsonString: String, type: Class<T>): T? {
        return moshi.adapter(type).fromJson(jsonString)
    }
    override fun <T> toJson(obj: T, type: Class<T>): String? {
        return moshi.adapter(type).toJson(obj)
    }
}
Sample converter class
    @ProvidedTypeConverter
    class JsonConverter(private val jsonParser: JsonParser) {
    
        @TypeConverter
        fun fromMetricsJson(jsonString: String): MetricsDomain {
            return jsonParser.fromJson(jsonString, MetricsDomain::class.java)
                ?: MetricsDomain() // Empty
        }
    
        @TypeConverter
        fun toMetricsJson(obj: MetricsDomain): String {
            return jsonParser.toJson(obj, MetricsDomain::class.java)
                ?: DEFAULT_VALUE_STRING // Empty
        }
    }
But how can I work with something like List?
@TypeConverter
    fun fromHistoricalValuesJson(jsonString: String): List<List<Double>> {
        return jsonParser.fromJson(jsonString, // How to do this in Moshi)
            ?: emptyList()
    } 
In Gson I think we can do it like object : TypeToken<ArrayList<List<Double>>>(){}.type, in Moshi we can use reified extension according to docs but I cannot do that in this case.
// We can just use a reified extension!
val adapter = moshi.adapter<List<Card>>()
Sample data class
@Parcelize
data class MetricsDomain(
    val riskMetricsDomain: RiskMetricsDomain = RiskMetricsDomain(),
    val roiByYearDomain: RoiByYearDomain = RoiByYearDomain(),
    val roiDataDomain: RoiDataDomain = RoiDataDomain(),
    val supplyDomain: SupplyDomain = SupplyDomain()
) : Parcelable
							
						Solution 1:[1]
Was able to do it using generic types thanks to @Eric comment.
class MoshiParser(private val moshi: Moshi) : JsonParser {
    override fun <T> fromJson(jsonString: String, type: Type): T? {
        return moshi.adapter<T>(type).fromJson(jsonString)
    }
    override fun <T> toJson(obj: T, type: Type): String? {
        return moshi.adapter<T>(type).toJson(obj)
    }
}
In your @ProvidedTypeConverter annotated class
    @TypeConverter
    fun fromListDoubleValuesJson(jsonString: String): List<List<Double>> {
        return jsonParser.fromJson(
            jsonString,
            Types.newParameterizedType(
                List::class.java,
                Types.newParameterizedType(List::class.java, Double::class.javaObjectType)
            )
        )
            ?: emptyList()
    }
    @TypeConverter
    fun toListDoubleValuesJson(obj: List<List<Double>>): String {
        return jsonParser.toJson(
            obj,
            Types.newParameterizedType(
                List::class.java,
                Types.newParameterizedType(List::class.java, Double::class.javaObjectType)
            )
        )
            ?: DEFAULT_VALUE_STRING
    }
    					Solution 2:[2]
Just put these 2 functions in a kotlin file :
val moshi: Moshi = Moshi
    .Builder()
    .add(KotlinJsonAdapterFactory())
    .build()    
inline fun <reified T> convertJsonToObject(json: String): T = 
    moshi.adapter(T::class.java).fromJson(json)
inline fun <reified T> convertObjectToJson(objectData: T): String =
    moshi.adapter(T::class.java).toJson(objectData)
And use it in your converter :
class ObjectTypeConverter {
    @TypeConverter
    fun objectToString(myObj: MyObject): String = convertObjectToJson(myObj)
    @TypeConverter
    fun stringToObject(myObjStr: String): MyObject = convertJsonToObject(myObjStr)
}
    					Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source | 
|---|---|
| Solution 1 | Bitwise DEVS | 
| Solution 2 | Richard Ory | 
