Performant Multiplatform Kotlin Serialization
Eric Cochran KotlinConf October 5, 2018
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' } }
Eric Cochran KotlinConf October 5, 2018
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' }
IJ plugin https://github.com/Kotlin/ kotlinx.serialization#working-in-intellij-idea
@Serializable data class Data(val number: Long) JSON.stringify(Data(8L)) ProtoBuf.dump(Data(8L)) val serializer: KSerializer<Data> = Data::class.serializer()
@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))
@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
@Serializable data class Data( @Serializable(with=DifferentLongSerializer::class) val number: Long )
@SerialInfo @Target(AnnotationTarget.PROPERTY) annotation class Special @Serializable data class Data( @Special val number: Long )
@Serializable data class Data( @SerialName("a number") val number: Long )
@Serializable data class Data( @Optional val number: Long )
@Serializable data class Data( @Optional val number: Long = 8L )
@Serializable data class Data( val number: Long? )
@Serializable data class Data(val number: Long) { @Serializer(forClass = Data::class) companion object {
TODO() }
TODO() } } }
@Serializable data class Data(val number: Long) { @Serializer(forClass = Data::class) companion object {
TODO() }
TODO() } } }
@Serializable data class Data(val number: Long) { @Serializer(forClass = Data::class) companion object: KSerializer<Data> {
TODO() }
TODO() } } }
@Serializer(forClass = Date::class)
TODO() }
TODO() } }
@Serializer(forClass = Date::class)
TODO() }
TODO() } }
SerializationStrategy - fun serialize(output: Encoder, obj : T)
SerializationStrategy - fun serialize(output: Encoder, obj : T) DeserializationStrategy - fun deserialize(input: Decoder): T
SerializationStrategy - fun serialize(output: Encoder, obj : T) DeserializationStrategy - fun deserialize(input: Decoder): T val descriptor: SerialDescriptor
@SerialInfo @Target(AnnotationTarget.PROPERTY) annotation class Special serialClassDesc.getAnnotationsForClass()
data class Pair<T, R>(val one: T, val two: R)
@Serializer(forClass = Pair::class) class PairSerializer<T, R>(val t: KSerializer<T>, val r: KSerializer<R>): KSerializer<Pair<T, R>> { }
@Serializer(forClass = Pair::class) class PairSerializer<T, R>(val t: KSerializer<T>, val r: KSerializer<R>): KSerializer<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) } }
@Serializer(forClass = Pair::class) class PairSerializer<T, R>(val t: KSerializer<T>, val r: KSerializer<R>): KSerializer<Pair<T, R>> {
) { val compositeEncoder = output.beginCollection(serialClassDesc, 2, r, t) compositeEncoder.encodeSerializableElement(serialClassDesc, 0, t, obj.one)
} }
@Serializable class Pair<R, T>(val one: R, val two: T) val serializer: KSerializer<Data> = Data::class.serializer() Pair.serializer(serializer, serializer)
fun serializerByTypeToken(type: Type): KSerializer<Any>
JSON Protobuf CBOR
JSON
Protobuf
CBOR
typealias Loader<T> = (DeserializationStrategy<Any>, T) -> Any typealias Saver<T> = (SerializationStrategy<Any>, Any) -> T
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
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
val json = JSON.plain val retrofit = Retrofit.Builder() .baseUrl(baseUrl) .client(client) .addConverterFactory(stringBased(contentType, json::parse, json::stringify)) .build()