Last active
July 28, 2020 10:37
-
-
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.
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
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() | |
} | |
} | |
} | |
} |
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
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