Skip to content

Instantly share code, notes, and snippets.

@ImaginativeShohag
Last active March 31, 2022 06:32
Show Gist options
  • Save ImaginativeShohag/0ec785a96cb7df52e9360e9e35619441 to your computer and use it in GitHub Desktop.
Save ImaginativeShohag/0ec785a96cb7df52e9360e9e35619441 to your computer and use it in GitHub Desktop.
Extension functions to convert object to json and json to object using Moshi. It also works with List, ArrayList, Collection etc.
object MoshiUtil {
fun getMoshi(): Moshi {
return Moshi.Builder()
.add(MutableCollectionJsonAdapter.FACTORY)
.build()
}
}
inline fun <reified T> String?.getObjFromJson(): T? {
if (this == null) return null
Timber.e("getObjFromJson: $this")
return try {
val jsonAdapter = MoshiUtil.getMoshi().adapter(T::class.java).lenient()
jsonAdapter.fromJson(this)
// Or, if you us it in the Navigation Component as url:
// jsonAdapter.fromJson(this.urlDecode())
} catch (e: Exception) {
Timber.e(e)
null
}
}
inline fun <reified T> T?.getJsonFromObj(): String? {
if (this == null) return null
Timber.e("getJsonFromObj: $this")
return try {
val jsonAdapter = MoshiUtil.getMoshi().adapter(T::class.java).lenient()
jsonAdapter.toJson(this)
// Or, if you us it in the Navigation Component as url:
// jsonAdapter.toJson(this).urlEncode()
} catch (e: Exception) {
Timber.e(e)
null
}
}
fun String.urlEncode(): String = URLEncoder.encode(this, "utf-8")
fun String.urlDecode(): String = URLDecoder.decode(this, "utf-8")
// To Object
val json = "..."
val user: User = json.getObjFromJson<User>()
// To Json String
val userJson: String = user.getJsonFromObj<User>()
import com.squareup.moshi.*
import com.squareup.moshi.JsonAdapter.Factory
import timber.log.Timber
import java.io.IOException
import java.lang.reflect.Type
import java.util.*
/**
* Converts collection types to JSON arrays containing their converted contents.
*
* Code is inspired from:
* https://github.com/square/moshi/blob/master/moshi/src/main/java/com/squareup/moshi/CollectionJsonAdapter.java
*/
internal abstract class MutableCollectionJsonAdapter<C : MutableCollection<T>?, T> private constructor(
private val elementAdapter: JsonAdapter<T>
) : JsonAdapter<C>() {
abstract fun newCollection(): C
@Throws(IOException::class)
override fun fromJson(reader: JsonReader): C {
val result = newCollection()
reader.beginArray()
while (reader.hasNext()) {
result?.add(elementAdapter.fromJson(reader)!!)
}
reader.endArray()
return result
}
@Throws(IOException::class)
override fun toJson(writer: JsonWriter, value: C?) {
writer.beginArray()
for (element in value!!) {
elementAdapter.toJson(writer, element)
}
writer.endArray()
}
override fun toString(): String {
return "$elementAdapter.collection()"
}
companion object {
val FACTORY = Factory { type, annotations, moshi ->
val rawType = Types.getRawType(type)
Timber.e("rawType: $rawType")
if (annotations.isNotEmpty()) return@Factory null
if (rawType == ArrayList::class.java || rawType == MutableList::class.java || rawType == MutableCollection::class.java) {
return@Factory newArrayListAdapter<Any>(
type,
moshi
).nullSafe()
}
null
}
private fun <T> newArrayListAdapter(
type: Type,
moshi: Moshi
): JsonAdapter<MutableCollection<T>> {
val elementType = Types.collectionElementType(type, MutableCollection::class.java)
val elementAdapter: JsonAdapter<T> = moshi.adapter(elementType)
return object : MutableCollectionJsonAdapter<MutableCollection<T>, T>(elementAdapter) {
override fun newCollection(): MutableCollection<T> {
return ArrayList()
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment