Created
August 3, 2022 12:27
-
-
Save arnabkd/5911c46bcb35d712d716df0f2aaf0b7e to your computer and use it in GitHub Desktop.
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.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