39 lines
1.6 KiB
Kotlin
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)
|
|
}
|
|
|