Skip to content

Instantly share code, notes, and snippets.

@mannodermaus
Last active July 28, 2020 10:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mannodermaus/c24f74dfa22dc45c0741066d5dd865c5 to your computer and use it in GitHub Desktop.
Save mannodermaus/c24f74dfa22dc45c0741066d5dd865c5 to your computer and use it in GitHub Desktop.
For when you're transitioning from Gson to Moshi, but those pesky JsonObject references still linger everywhere.
import com.google.gson.Gson
import com.google.gson.JsonArray
import com.google.gson.JsonElement
import com.google.gson.JsonNull
import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import java.lang.reflect.Type
@Deprecated(message = "Remove this as soon as Gson has been fully replaced")
class GsonCompatAdapter(private val gson: Gson) : JsonAdapter<JsonElement>() {
class Factory(private val gson: Gson = Gson()) : JsonAdapter.Factory {
override fun create(type: Type, annotations: MutableSet<out Annotation>, moshi: Moshi): JsonAdapter<*>? {
// Check if the annotated field is any of Gson's types
return if (JsonElement::class.java.isAssignableFrom(Types.getRawType(type))) {
GsonCompatAdapter(gson)
} else {
null
}
}
}
override fun fromJson(reader: JsonReader): JsonElement? =
when (val token = reader.peek()) {
JsonReader.Token.NULL -> {
reader.nextNull<JsonObject>()
null
}
JsonReader.Token.BEGIN_OBJECT -> {
val map = reader.readJsonValue()
gson.fromJson(gson.toJson(map), JsonObject::class.java)
}
JsonReader.Token.BEGIN_ARRAY -> {
val list = reader.readJsonValue()
gson.fromJson(gson.toJson(list), JsonArray::class.java)
}
JsonReader.Token.STRING -> JsonPrimitive(reader.nextString())
JsonReader.Token.NUMBER -> JsonPrimitive(reader.readJsonValue() as Number)
JsonReader.Token.BOOLEAN -> JsonPrimitive(reader.readJsonValue() as Boolean)
else -> throw IllegalArgumentException("cannot convert $token to JsonObject")
}
override fun toJson(writer: JsonWriter, value: JsonElement?) {
if (value == null) {
writer.nullValue()
} else {
writer.writeRecursive(value)
}
}
private fun JsonWriter.writeRecursive(element: JsonElement) {
when (element) {
is JsonNull -> nullValue()
is JsonPrimitive -> {
when {
element.isNumber -> value(element.asNumber)
element.isBoolean -> value(element.asBoolean)
element.isString -> value(element.asString)
else -> throw IllegalArgumentException("cannot write JsonPrimitive to JsonWriter: $element")
}
}
is JsonArray -> {
beginArray()
element.forEach { item ->
writeRecursive(item)
}
endArray()
}
is JsonObject -> {
beginObject()
element.keySet().forEach { key ->
name(key)
writeRecursive(element.get(key))
}
endObject()
}
}
}
}
val gson = Gson()
val moshi = Moshi.Builder()
.add(GsonCompatAdapter.Factory(gson))
.build()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment