typeshare icon indicating copy to clipboard operation
typeshare copied to clipboard

Improve Kotlin API for anonymous structs

Open snowsignal opened this issue 1 year ago • 0 comments

Take the following code snippet:

#[typeshare]
#[serde(tag = "type", content = "content")]
pub enum Menu {
    Breadsticks {
        marinara: bool
    },
    Pizza {
        pepperoni: bool,
        anchovies: bool
    },
}

This will generate the following output:

@Serializable
data class MenuBreadsticksInner (
  val marinara: Boolean
)

@Serializable
data class MenuPizzaInner (
  val pepperoni: Boolean
  val anchovies: Boolean
)

@Serializable
sealed class Menu {
  @Serializable
  @SerialName("Breadsticks")
  data class Breadsticks(val content: MenuBreadsticksInner): Menu()
  @Serializable
  @SerialName("Pizza")
  data class Pizza(val content: MenuPizzaInner): Menu()
}

However, this approach means we have to use .content to access a field.

Ideally, the Kotlin output should look more like this to be more ergonomic:

sealed interface Menu {
    interface Breadsticks : Menu {
        val marinara: Boolean
    }
    interface Pizza: Menu {
        val pepperoni: Boolean
        val anchovies: Boolean
    }
}

This would let us do:

fun main() {
   val test: Menu = object : Menu.Breadsticks {
       override val marinara: Boolean = true
   }
   
   when (test) {
       is Menu.Breadsticks -> println(test.marinara)
       is Menu.Pizza -> println(test.pepperoni)
   }
}

snowsignal avatar Apr 03 '23 17:04 snowsignal