Skip to content

Instantly share code, notes, and snippets.

@artzmb
Created November 21, 2019 14:13
Show Gist options
  • Save artzmb/3d734c5f6e5fee3ab61103e0eeabf917 to your computer and use it in GitHub Desktop.
Save artzmb/3d734c5f6e5fee3ab61103e0eeabf917 to your computer and use it in GitHub Desktop.
import com.google.gson.Gson
import com.google.gson.TypeAdapter
import com.google.gson.TypeAdapterFactory
import com.google.gson.reflect.TypeToken
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonWriter
import com.google.gson.stream.JsonToken
import com.google.gson.stream.MalformedJsonException
class SuddenArrayTypeAdapterFactory : TypeAdapterFactory {
override fun <T : Any?> create(gson: Gson?, type: TypeToken<T>?): TypeAdapter<T> {
@Suppress("UNCHECKED_CAST")
val elementTypeAdapter = gson?.getAdapter(TypeToken.get(type?.rawType)) as TypeAdapter<T>
return SuddenArrayTypeAdapter(elementTypeAdapter)
}
class SuddenArrayTypeAdapter<T>(
private val elementTypeAdapter: TypeAdapter<T>
) : TypeAdapter<T>() {
override fun write(output: JsonWriter, value: T) {
throw UnsupportedOperationException()
}
override fun read(input: JsonReader): T? {
return when (val token = input.peek()) {
JsonToken.NULL -> null
JsonToken.BEGIN_ARRAY -> {
val list = mutableListOf<T>()
input.beginArray()
while (input.hasNext()) {
list.add(elementTypeAdapter.read(input))
}
input.endArray()
if (list.isEmpty()) null else list.first()
}
JsonToken.BOOLEAN, JsonToken.NUMBER, JsonToken.STRING, JsonToken.BEGIN_OBJECT -> {
elementTypeAdapter.read(input)
}
else -> throw MalformedJsonException("Unexpected token: $token")
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment