Performant Multiplatform Kotlin Serialization Eric Cochran - - PowerPoint PPT Presentation

performant multiplatform kotlin serialization
SMART_READER_LITE
LIVE PREVIEW

Performant Multiplatform Kotlin Serialization Eric Cochran - - PowerPoint PPT Presentation

Performant Multiplatform Kotlin Serialization Eric Cochran KotlinConf October 5, 2018 Performant Multiplatform Kotlin Serialization 0.8 Why? Get Started buildscript { repositories { maven { url 'https://kotlin.bintray.com/kotlinx' } }


slide-1
SLIDE 1

Performant Multiplatform Kotlin Serialization

Eric Cochran KotlinConf October 5, 2018

slide-2
SLIDE 2

Performant Multiplatform Kotlin Serialization

0.8

slide-3
SLIDE 3

Why?

slide-4
SLIDE 4

Get Started

buildscript { repositories { maven { url 'https://kotlin.bintray.com/kotlinx' } } dependencies { classpath 'org.jetbrains.kotlinx:kotlinx-gradle-serialization-plugin:serializerVersion' } } apply plugin: 'kotlinx-serialization' dependencies { implementation 'org.jetbrains.kotlinx:kotlinx-serialization-runtime:serializerVersion' }

slide-5
SLIDE 5

Get Started

IJ plugin https://github.com/Kotlin/ kotlinx.serialization#working-in-intellij-idea

slide-6
SLIDE 6

Run it

@Serializable data class Data(val number: Long) JSON.stringify(Data(8L)) ProtoBuf.dump(Data(8L)) val serializer: KSerializer<Data> = Data::class.serializer()

slide-7
SLIDE 7

Run it

@Serializable data class Data(val number: Long) JSON.stringify(Data(8L)) ProtoBuf.dump(Data(8L)) val serializer: KSerializer<Data> = Data::class.serializer() JSON.stringify(serializer, Data(8L))

slide-8
SLIDE 8

Run it

@Serializable data class Data(val number: Long) val serializer: KSerializer<Data> = Data::class.serializer() val listSerializer: KSerializer<List<Data>> = serializer.list val setSerializer: KSerializer<Set<Data>> = serializer.set val mapSerializer: KSerializer<Map<User, User>> = (serializer to serializer).map

slide-9
SLIDE 9

Run it

@Serializable data class Data( @Serializable(with=DifferentLongSerializer::class) val number: Long )

slide-10
SLIDE 10

Run it

@SerialInfo @Target(AnnotationTarget.PROPERTY) annotation class Special @Serializable data class Data( @Special val number: Long )

slide-11
SLIDE 11

Run it

@Serializable data class Data( @SerialName("a number") val number: Long )

slide-12
SLIDE 12

Run it

@Serializable data class Data( @Optional val number: Long )

slide-13
SLIDE 13

Run it

@Serializable data class Data( @Optional val number: Long = 8L )

slide-14
SLIDE 14

Run it

@Serializable data class Data( val number: Long? )

slide-15
SLIDE 15

Custom Serialization

@Serializable data class Data(val number: Long) { @Serializer(forClass = Data::class) companion object {

  • verride fun serialize(output: Encoder, obj: Data) {

TODO() }

  • verride fun deserialize(input: Decoder): Data {

TODO() } } }

slide-16
SLIDE 16

Custom Serialization

@Serializable data class Data(val number: Long) { @Serializer(forClass = Data::class) companion object {

  • verride fun serialize(output: Encoder, obj: Data) {

TODO() }

  • verride fun deserialize(input: Decoder): Data {

TODO() } } }

slide-17
SLIDE 17

Custom Serialization

@Serializable data class Data(val number: Long) { @Serializer(forClass = Data::class) companion object: KSerializer<Data> {

  • verride fun serialize(output: Encoder, obj: Data) {

TODO() }

  • verride fun deserialize(input: Decoder): Data {

TODO() } } }

slide-18
SLIDE 18

Platform Types

@Serializer(forClass = Date::class)

  • bject DateSerializer: KSerializer<Date> {
  • verride fun serialize(output: Encoder, obj: Date) {

TODO() }

  • verride fun deserialize(input: Decoder): Date {

TODO() } }

slide-19
SLIDE 19

Platform Types

@Serializer(forClass = Date::class)

  • bject DateSerializer: KSerializer<Date> {
  • verride fun serialize(output: Encoder, obj: Date) {

TODO() }

  • verride fun deserialize(input: Decoder): Date {

TODO() } }

slide-20
SLIDE 20

KSerializer

SerializationStrategy - fun serialize(output: Encoder, obj : T)

slide-21
SLIDE 21

KSerializer

SerializationStrategy - fun serialize(output: Encoder, obj : T) DeserializationStrategy - fun deserialize(input: Decoder): T

slide-22
SLIDE 22

KSerializer

SerializationStrategy - fun serialize(output: Encoder, obj : T) DeserializationStrategy - fun deserialize(input: Decoder): T val descriptor: SerialDescriptor

slide-23
SLIDE 23

KSerialClassDesc

@SerialInfo @Target(AnnotationTarget.PROPERTY) annotation class Special serialClassDesc.getAnnotationsForClass()

slide-24
SLIDE 24

Readers and Writers

data class Pair<T, R>(val one: T, val two: R)

slide-25
SLIDE 25

Readers and Writers

@Serializer(forClass = Pair::class) class PairSerializer<T, R>(val t: KSerializer<T>, val r: KSerializer<R>): KSerializer<Pair<T, R>> { }

slide-26
SLIDE 26

Readers and Writers

@Serializer(forClass = Pair::class) class PairSerializer<T, R>(val t: KSerializer<T>, val r: KSerializer<R>): KSerializer<Pair<T, R>> {

  • verride fun load(input: Decoder): Pair<T, R> {

val compositeDecoder = input.beginStructure(serialClassDesc, t, r) var index = compositeDecoder.decodeElementIndex(serialClassDesc) val one = compositeDecoder.decodeSerializableElement(serialClassDesc, index, t) index = compositeDecoder.decodeElementIndex(serialClassDesc) val two = compositeDecoder.decodeSerializableElement(serialClassDesc, index, r) input.endStructure(serialClassDesc) return Pair(one, two) } }

slide-27
SLIDE 27

Readers and Writers

@Serializer(forClass = Pair::class) class PairSerializer<T, R>(val t: KSerializer<T>, val r: KSerializer<R>): KSerializer<Pair<T, R>> {

  • verride fun save(
  • utput: Encoder,
  • bj: Pair<T, R>

) { val compositeEncoder = output.beginCollection(serialClassDesc, 2, r, t) compositeEncoder.encodeSerializableElement(serialClassDesc, 0, t, obj.one)

  • utput.encodeSerializableElement(serialClassDesc, 1, r, obj.two)
  • utput.endStructure(serialClassDesc)

} }

slide-28
SLIDE 28

Simpler Generics

@Serializable class Pair<R, T>(val one: R, val two: T) val serializer: KSerializer<Data> = Data::class.serializer() Pair.serializer(serializer, serializer)

slide-29
SLIDE 29

Adapting from Java Types

fun serializerByTypeToken(type: Type): KSerializer<Any>

slide-30
SLIDE 30

Formats

JSON Protobuf CBOR

slide-31
SLIDE 31

Formats

JSON

  • JSON.parse(deserializationStrategy, string)
  • JSON.stringify(serializationStrategy, data)

Protobuf

  • ProtoBuf.load(deserializationStrategy, byteArray)
  • ProtoBuf.dump(serializationStrategy, data)

CBOR

  • CBOR.load(deserializationStrategy, byteArray)
  • CBOR.dump(serializationStrategy, data)
slide-32
SLIDE 32
slide-33
SLIDE 33

typealias Loader<T> = (DeserializationStrategy<Any>, T) -> Any typealias Saver<T> = (SerializationStrategy<Any>, Any) -> T

https://github.com/JakeWharton/ retrofit2-kotlinx-serialization-converter/

slide-34
SLIDE 34

https://github.com/JakeWharton/ retrofit2-kotlinx-serialization-converter/

typealias Loader<T> = (DeserializationStrategy<Any>, T) -> Any typealias Saver<T> = (SerializationStrategy<Any>, Any) -> T fun stringBased( contentType: MediaType, loader: Loader<String>, saver: Saver<String> ): Converter.Factory

slide-35
SLIDE 35

https://github.com/JakeWharton/ retrofit2-kotlinx-serialization-converter/

typealias Loader<T> = (DeserializationStrategy<Any>, T) -> Any typealias Saver<T> = (SerializationStrategy<Any>, Any) -> T fun bytesBased( contentType: MediaType, loader: Loader<ByteArray>, saver: Saver<ByteArray> ): Converter.Factory

slide-36
SLIDE 36

https://github.com/JakeWharton/ retrofit2-kotlinx-serialization-converter/

val json = JSON.plain val retrofit = Retrofit.Builder() .baseUrl(baseUrl) .client(client) .addConverterFactory(stringBased(contentType, json::parse, json::stringify)) .build()

slide-37
SLIDE 37
slide-38
SLIDE 38

https://github.com/Kotlin/ kotlinx.serialization/

@Eric_Cochran