Skip to content

Instantly share code, notes, and snippets.

@fteychene
Created June 17, 2019 12:41
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 fteychene/c4964b548487bc144848c71f87b7d3ac to your computer and use it in GitHub Desktop.
Save fteychene/c4964b548487bc144848c71f87b7d3ac to your computer and use it in GitHub Desktop.
Helios sealed classes encoder/decoder test
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.3.31'
}
apply plugin: 'kotlin-kapt' //optional
group 'io.saagie.playground'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
maven { url = uri("https://dl.bintray.com/47deg/helios") }
}
def arrow_version = "0.9.0"
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
compile "com.47deg:helios-core:0.1.0"
compile "com.47deg:helios-parser:0.1.0"
compile "com.47deg:helios-optics:0.1.0"
kapt "com.47deg:helios-meta:0.1.0"
kapt "com.47deg:helios-dsl-meta:0.1.0"
compile "io.arrow-kt:arrow-core-data:$arrow_version"
compile "io.arrow-kt:arrow-core-extensions:$arrow_version"
compile "io.arrow-kt:arrow-syntax:$arrow_version"
compile "io.arrow-kt:arrow-typeclasses:$arrow_version"
compile "io.arrow-kt:arrow-extras-data:$arrow_version"
compile "io.arrow-kt:arrow-extras-extensions:$arrow_version"
kapt "io.arrow-kt:arrow-meta:$arrow_version"
compile "io.arrow-kt:arrow-query-language:$arrow_version" //optional
compile "io.arrow-kt:arrow-free-data:$arrow_version" //optional
compile "io.arrow-kt:arrow-free-extensions:$arrow_version" //optional
compile "io.arrow-kt:arrow-mtl:$arrow_version" //optional
compile "io.arrow-kt:arrow-effects-data:$arrow_version" //optional
compile "io.arrow-kt:arrow-effects-extensions:$arrow_version" //optional
compile "io.arrow-kt:arrow-effects-io-extensions:$arrow_version" //optional
compile "io.arrow-kt:arrow-effects-rx2-data:$arrow_version" //optional
compile "io.arrow-kt:arrow-effects-rx2-extensions:$arrow_version" //optional
compile "io.arrow-kt:arrow-effects-reactor-data:$arrow_version" //optional
compile "io.arrow-kt:arrow-effects-reactor-extensions:$arrow_version" //optional
compile "io.arrow-kt:arrow-optics:$arrow_version" //optional
compile "io.arrow-kt:arrow-generic:$arrow_version" //optional
compile "io.arrow-kt:arrow-recursion-data:$arrow_version" //optional
compile "io.arrow-kt:arrow-recursion-extensions:$arrow_version" //optional
compile "io.arrow-kt:arrow-query-language:$arrow_version" //optional
compile "io.arrow-kt:arrow-integration-retrofit-adapter:$arrow_version" //optional
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
import arrow.core.Either
import arrow.core.extensions.either.applicative.product
import arrow.core.flatMap
import arrow.core.left
import arrow.core.right
import helios.core.*
import helios.instances.decoder
import helios.json
import helios.typeclasses.Decoder
import helios.typeclasses.Encoder
sealed class Test {
companion object
}
@json
data class A(val a: String) : Test() {
companion object
}
@json
data class B(val b: String) : Test() {
companion object
}
fun Test.Companion.encoder() = object : Encoder<Test> {
override fun Test.encode(): Json = let {
JsObject(mapOf(
"type" to JsString(it::class.java.simpleName),
"value" to when (it) {
is A -> with(A.encoder()) { it.encode() }
is B -> with(B.encoder()) { it.encode() }
}))
}
}
fun typeDecoder(type: String): Either<DecodingError, Decoder<Test>> = when(type) {
A::class.java.simpleName -> A.decoder().right()
B::class.java.simpleName -> B.decoder().right()
else -> StringDecodingError(JsString("type invalid")).left()
}
fun Test.Companion.decoder() = object: Decoder<Test> {
override fun decode(value: Json): Either<DecodingError, Test> =
value["type"].fold({ KeyNotFound("type").left() }, { String.decoder().decode(it).flatMap(::typeDecoder) })
.product(value["value"] .fold({ KeyNotFound("value").left() }, {it.right() }))
.flatMap { (decoder, value) -> decoder.decode(value) }
}
object Sample {
@JvmStatic
fun main(args: Array<String>) {
println(with(Test.encoder()) { B(b = "Coucou").encode() }.toJsonString())
// {"type":"B","value":{"b":"Coucou"}}
println(Json.parseFromString("""{"type":"B","value":{"b":"Valeur pour le type B"}}""").flatMap { Test.decoder().decode(it) })
// {"type":"B","value":{"b":"Valeur pour le type B"}}
println(with(Test.encoder()) { A(a = "Valeur pour le type A").encode() }.toJsonString())
// {"type":"A","value":{"a":"Valeur pour le type A"}}
println(Json.parseFromString("""{"type":"A","value":{"a":"Valeur pour le type A"}}""").flatMap { Test.decoder().decode(it) })
// Right(b=A(a=Valeur pour le type A))
println(Json.parseFromString("""{"value":{"a":"Valeur pour le type A"}}""").flatMap { Test.decoder().decode(it) })
// Left(a=KeyNotFound(name=type))
println(Json.parseFromString("""{"type":"C","value":{"a":"Valeur pour le type A"}}""").flatMap { Test.decoder().decode(it) })
// Left(a=StringDecodingError(value=JsString(value=type invalid)))
println(Json.parseFromString("""{"type":"A"}""").flatMap { Test.decoder().decode(it) })
// Left(a=KeyNotFound(name=value))
println(Json.parseFromString("""{"type":"A", "value":{"b":"Valeur pour le type B"}}""").flatMap { Test.decoder().decode(it) })
// Left(a=KeyNotFound(name=a))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment