Skip to content

Instantly share code, notes, and snippets.

@monday8am
Last active February 17, 2021 20:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save monday8am/950565efe888dc8f53e5f34f254b1d23 to your computer and use it in GitHub Desktop.
Save monday8am/950565efe888dc8f53e5f34f254b1d23 to your computer and use it in GitHub Desktop.
Result deserialization
override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): Result<*, *>? {
return when {
// Is it a JsonObject? Bingo!
json?.isJsonObject == true -> {
// Let's try to extract the type in order
// to deserialize this object
val parameterizedType = typeOfT as ParameterizedType
// Returns an Ok with the value deserialized
return Result.ok(context?.deserialize<Any>(json, parameterizedType.actualTypeArguments[0])!!)
}
// Wow, is it an array of objects?
json?.isJsonArray == true -> {
// First, let's try to get the array type
val parameterizedType = typeOfT as ParameterizedType
// check if the array contains a generic type too,
// for example, List<Result<T, E>>
if (parameterizedType.actualTypeArguments[0] is WildcardType) {
// In case of yes, let's try to get the type from the
// wildcard type (*)
val internalListType = (parameterizedType.actualTypeArguments[0] as WildcardType).upperBounds[0] as ParameterizedType
// Deserialize the array with the base type Any
// It will give us an array full of linkedTreeMaps (the json)
val arr = context?.deserialize<Any>(json, parameterizedType.actualTypeArguments[0]) as ArrayList<*>
// Iterate the array and
// this time, try to deserialize each member with the discovered
// wildcard type and create new array with these values
val result = arr.map { linkedTreeMap ->
val jsonElement = gson.toJsonTree(linkedTreeMap as LinkedTreeMap<*, *>).asJsonObject
return@map context.deserialize<Any>(jsonElement, internalListType.actualTypeArguments[0])
}
// Return the result inside the Ok state
return Result.ok(result)
} else {
// Fortunately it is a simple list, like Array<String>
// Just get the type as with a JsonObject and return an Ok
return Result.ok(context?.deserialize<Any>(json, parameterizedType.actualTypeArguments[0])!!)
}
}
// It is not a JsonObject or JsonArray
// Let's returns the default state Loading.
else -> Result.Loading
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment