Last active
February 17, 2021 20:34
-
-
Save monday8am/950565efe888dc8f53e5f34f254b1d23 to your computer and use it in GitHub Desktop.
Result deserialization
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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