Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Extending kotlinx.serialization functionality w...

Extending kotlinx.serialization functionality with Arrow Meta

Migrating from Jackson to kotlinx.serialization may be quite a challenge due to differences in approaches. One of them is not having a global naming strategy. But can we solve this? Sure, we can with Arrow Meta.

Arrow Meta is a functional companion to Kotlin's compiler. This library opens a way to write compiler plugins, linters and other source transformations.

In this talk, we are going to cover the following:

Setup a multi module project for compiler plugin development with gradle
Overview of Arrow Meta features
Use case: Adding a global naming strategy to Kotlin Serialization

Karin-Aleksandra Monoid

July 03, 2021
Tweet

More Decks by Karin-Aleksandra Monoid

Other Decks in Technology

Transcript

  1. About Senior Software Engineer Background in Kotlin & Scala (both

    front and backend) Living in Berlin with two cats
  2. Agenda • Why? • What is Arrow Meta • Sample

    project: description • Diving into details • Showtime!
  3. Project stack Just backend with Ktor + Arrow Jackson was

    kind of "default" Smooth but not Kotlin-first
  4. Kotlinx.serialization Pros Kotlin-first No boilerplate for sealed classes Cons Not

    a lot of serializers out of the box Nuances with transients in abstract classes No global naming strategy
  5. Setting: a Zoo • various animals (actually, only cats and

    dogs) • various sources (= 3rd party services) • various standards of documentation (in JSON format with different naming policies)
  6. A generic cat @Serializable data class Cat( val name: String,

    val age: Int, val ownerName: String, val breed: String )
  7. Register your extension class SerialNamePlugin : Meta { @ExperimentalContracts override

    fun intercept( ctx: CompilerContext ): List<CliPlugin> = listOf( serialNameGenerator ) }
  8. Decide the phase • classDeclaration - class signature (name, annotations,

    parameters etc.) • finallySection - finally block • destructuringDeclaration - like in val (first, second) = listOf(first, second) • classBody - functions, properties, companions And others
  9. Decide the phase • classDeclaration - class signature (name, annotations,

    parameters etc.) • finallySection - finally block • destructuringDeclaration - like in val (first, second) = listOf(first, second) • classBody - functions, properties, companions And others
  10. Add transformations val newDeclaration = """ |$`@annotations` |$kind$name$`(typeParameters)` |$paramListString {

    |$body |} """.trimMargin() Transform.Companion.replace(classElement, newDeclaration.`class`.syntheticScope)