Advertisement
Guest User

Untitled

a guest
Oct 16th, 2019
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.46 KB | None | 0 0
  1. import kotlinx.serialization.*
  2. import kotlinx.serialization.internal.ArrayListSerializer
  3. import kotlinx.serialization.internal.StringDescriptor
  4. import kotlinx.serialization.json.Json
  5. import kotlinx.serialization.modules.SerializersModule
  6.  
  7. @Serializable
  8. sealed class Foo {
  9.  
  10. @Serializable
  11. @SerialName("foo_a")
  12. data class A(val s: String = "hunter") : Foo()
  13.  
  14. sealed class B {
  15. @Serializable
  16. @SerialName("foo_b0")
  17. data class B0(val i: Int = 42) : Foo()
  18.  
  19. @Serializable
  20. @SerialName("foo_b1")
  21. data class B1(val b: Boolean = false) : Foo()
  22. }
  23. }
  24.  
  25. @Serializable
  26. data class FooWrapper(@Polymorphic val foo: Foo)
  27.  
  28. /**
  29. * Foo Wrapper is used when we want to serialize Foo as a direct property.
  30. */
  31. @Serializer(forClass = Foo::class)
  32. object FooSerializer : KSerializer<Foo> {
  33. private val json by lazy { Json(context = fooContext) }
  34.  
  35. override val descriptor: SerialDescriptor = StringDescriptor.withName("foo")
  36.  
  37. override fun deserialize(decoder: Decoder): Foo =
  38. decoder.decodeString()
  39. .let { str -> json.parse(FooWrapper.serializer(), str).foo }
  40.  
  41. override fun serialize(encoder: Encoder, obj: Foo) =
  42. FooWrapper(obj)
  43. .let { fooWrapped -> json.stringify(FooWrapper.serializer(), fooWrapped) }
  44. .let(encoder::encodeString)
  45. }
  46.  
  47. /**
  48. * However, if we want to serialize Foo as part of a list, we need to use another
  49. * custom serializer! In this case: [FooListSerializer].
  50. */
  51. @Serializable
  52. data class MultiFoos(@Serializable(with = FooListSerializer::class) val foos: List<Foo>)
  53.  
  54. val fooContext = SerializersModule {
  55. polymorphic<Foo> {
  56. Foo.A::class with Foo.A.serializer()
  57. Foo.B.B0::class with Foo.B.B0.serializer()
  58. Foo.B.B1::class with Foo.B.B1.serializer()
  59. }
  60. }
  61.  
  62. object FooListSerializer :
  63. KSerializer<List<Foo>> by ArrayListSerializer<Foo>(PolymorphicSerializer(Foo::class) as KSerializer<Foo>)
  64.  
  65. fun main(args: Array<String>) {
  66. val fooA = Foo.A()
  67. val fooB0 = Foo.B.B0()
  68. val fooB1 = Foo.B.B1()
  69. val foos = MultiFoos(listOf(fooA, fooB0, fooB1))
  70.  
  71. Json(context = fooContext).apply {
  72. stringify(MultiFoos.serializer(), foos)
  73. .also(::println)
  74. .let { str -> parse(MultiFoos.serializer(), str) }
  75. .also(::println)
  76. }
  77.  
  78. println("---")
  79.  
  80. Json.apply {
  81. stringify(FooSerializer, fooA)
  82. .also(::println)
  83. .let { str -> parse(FooSerializer, str) }
  84. .also(::println)
  85. }
  86. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement