app/app/src/main/java/com/danilafe/fencelessgrazing/requests/GsonListener.kt

39 lines
1.6 KiB
Kotlin

package com.danilafe.fencelessgrazing.requests
import android.util.Log
import com.android.volley.Response
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import java.lang.reflect.Type
/**
* It appears as though a type parameter, even on that's `reified`, is erased when an anonymous
* object is declared inside an `inline` function. This means that [Gson] serialization with
* a [TypeToken] created inside this anonymous object wil _still_ fail, even though the
* surrounding function is `inline` and with a `reified` type. To work around this,
* we create the type in the function itself, and pass it as an argument to this
* [GsonListener].
*
* @param listener the underlying listener expecting a value of type [T].
* @param type the type to which [Gson] should deserialize the expected string.
*/
class GsonListener<T>(val listener: Response.Listener<T>, private val type: Type) : Response.Listener<String> {
override fun onResponse(response: String?) {
val transformed = response?.let { Gson().fromJson<T>(it, type) }
listener.onResponse(transformed)
}
}
/**
* Converts a [Response.Listener] of an arbitrary type [T] to a listener of type [String].
* This is done by converting the input [String] into [T] via [Gson].
* This function must be reified to prevent type erasure.
*
* @receiver the listener that will be called when the [String] is converted into [T].
* @return the resulting [String]-based listener.
*/
inline fun <reified T> Response.Listener<T>.toGsonListener(): Response.Listener<String> {
return GsonListener(this, object : TypeToken<T>(){}.type)
}