Skip to content

Instantly share code, notes, and snippets.

@arnabkd
Created August 3, 2022 12:27
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 arnabkd/5911c46bcb35d712d716df0f2aaf0b7e to your computer and use it in GitHub Desktop.
Save arnabkd/5911c46bcb35d712d716df0f2aaf0b7e to your computer and use it in GitHub Desktop.
import com.fasterxml.jackson.annotation.JsonProperty
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonClass
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import com.squareup.moshi.internal.Util
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import org.http4k.format.ConfigurableMoshi
import org.http4k.format.EventAdapter
import org.http4k.format.ListAdapter
import org.http4k.format.MapAdapter
import org.http4k.format.ThrowableAdapter
import org.http4k.format.asConfigurable
import org.http4k.format.withStandardMappings
import java.lang.reflect.Type
@JsonClass(generateAdapter = true)
sealed class Principal
@JsonClass(generateAdapter = true)
object AnonymousUser : Principal() {
val _empty: String? = null
}
@JsonClass(generateAdapter = true)
data class GoogleUser(
val email: String,
) : Principal()
@JsonClass(generateAdapter = true)
data class GithubUser(
val id: Int,
val login: String,
val name: String,
val email: String,
@JsonProperty("avatar_url")
val avatarUrl: String,
) : Principal()
fun main() {
val user = AnonymousUser
val input = MyMoshi.asJsonString(user, Principal::class)
val result = MyMoshi.asA<Principal>(input)
println(result)
}
object MyMoshi : ConfigurableMoshi(
Moshi.Builder()
.addLast(KotlinJsonAdapterFactory())
.addLast(EventAdapter)
.addLast(ThrowableAdapter)
.addLast(ListAdapter)
.addLast(MapAdapter)
.addLast(PrincipalAdapterFactory)
.asConfigurable()
.withStandardMappings()
.done()
)
object PrincipalAdapterFactory: JsonAdapter.Factory {
override fun create(
type: Type,
annotations: MutableSet<out Annotation>,
moshi: Moshi,
): JsonAdapter<*>? = when(type) {
Principal::class.java -> PrincipalAdapter(moshi)
else -> null
}
private class PrincipalAdapter(moshi: Moshi): JsonAdapter<Principal>() {
private val mapAdapter: JsonAdapter<MutableMap<String, Any?>> =
moshi.adapter(Types.newParameterizedType(Map::class.java, String::class.java, Any::class.java))
private val anonymousUserAdapter = moshi.adapter(AnonymousUser::class.java)
private val githubUserAdapter = moshi.adapter(GithubUser::class.java)
private val googleUserAdapter = moshi.adapter(GoogleUser::class.java)
override fun fromJson(reader: JsonReader): Principal? {
val mapValues = mapAdapter.fromJson(reader)
val type = mapValues?.get("type") ?: throw Util.missingProperty("type", "type", reader)
val properties = mapValues["properties"] ?: throw Util.missingProperty("properties", "properties", reader)
return when (type) {
"anonymous" -> anonymousUserAdapter.fromJsonValue(properties)
"githubUser" -> githubUserAdapter.fromJsonValue(properties)
"googleUser" -> googleUserAdapter.fromJsonValue(properties)
else -> TODO()
}
}
override fun toJson(writer: JsonWriter, value: Principal?) {
when(value) {
is AnonymousUser -> anonymousUserAdapter.toJson(writer, value)
is GithubUser -> TODO()
is GoogleUser -> TODO()
null -> {
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment