Skip to content

Instantly share code, notes, and snippets.

@niwatly
Last active June 26, 2023 19:34
Show Gist options
  • Save niwatly/07ac83f8b36edcf1b8c25278319db519 to your computer and use it in GitHub Desktop.
Save niwatly/07ac83f8b36edcf1b8c25278319db519 to your computer and use it in GitHub Desktop.
Gson Utils by Kotlin
//convert gson String to Map<K, V>. Crash when invalid structure found
inline fun <reified K, reified V> String.toMapByGson(): Map<K, V> = if (isNotEmpty()) {
Gson().fromJson<HashMap<K, V>>(this, TypeToken.getParameterized(HashMap::class.java, K::class.java, V::class.java).type)
} else {
mapOf<K, V>()
}
//convert gson String to List<T>. Crash when invalid structure found
inline fun <reified T> String.toListByGson(): List<T> = if (isNotEmpty()) {
Gson().fromJson<List<T>>(this, TypeToken.getParameterized(ArrayList::class.java, T::class.java).type)
} else {
listOf<T>()
}
//convert gson String to T. Crash when invalid structure found
inline fun <reified T> String.toObjectByGson(): T = Gson().fromJson<T>(this, T::class.java)
//convert gson String to T. Crash when invalid structure found
fun <T> String.toObjectByGson(cls: Class<T>): T = Gson().instance.fromJson<T>(this, cls)
//convert T to String
fun Any.toStringByGson(): String = Gson().toJson(this)
/**
* persistence property that is convertable to Gson String on Fragment.
* The set value also write to Fragment.arguments, and always read from Fragment.arguments if need.
*/
class GsonableProperty<T : Any>(private val defaultValue: T? = null, private val cls: Class<T>) : kotlin.properties.ReadWriteProperty<Fragment, T> {
var value: T? = null
override operator fun getValue(thisRef: android.support.v4.app.Fragment, property: kotlin.reflect.KProperty<*>): T {
if (value == null) {
val args = thisRef.arguments ?: throw IllegalStateException("Cannot read property ${property.name} if no arguments have been set")
@Suppress("UNCHECKED_CAST")
value = args.getString(property.name).toObjectByGson(cls)
}
return (value ?: defaultValue) ?: throw IllegalStateException("Property ${property.name} could not be read")
}
override operator fun setValue(thisRef: android.support.v4.app.Fragment, property: kotlin.reflect.KProperty<*>, value: T) {
val args = thisRef.arguments?.let {
it
} ?: run {
Bundle().also {
thisRef.arguments = it
}
}
val key = property.name
this.value = value
args.putString(key, value.toStringByGson())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment