sealed enum
An open source Kotlin annotation processor for replacing enum classes with sealed classes of objects.
Why we built it.
In Kotlin, sealed classes are more powerful and more flexible than enums, but enums can still do some things that sealed classes can't. We recognized that a sealed class of objects is strictly more powerful than enums, given a bit of repeated boilerplate code:
sealed class Alpha {
object Beta : Alpha()
object Gamma : Alpha()
@GenSealedEnum
companion object
}
println(Beta.ordinal) // 0
println(Beta.name) // "Beta"
println(Alpha.values) // [Alpha$Beta@491cc5c9, Alpha$Gamma@74ad1f1f]
println(Alpha.valueOf("Beta")) // Alpha$Beta@491cc5c9
sealed-enum
generates that boilerplate code automatically, so we can replace
enums and gain all of the benefits of using sealed classes without the tedious and error-prone
maintenance of boilerplate.
How it works.
If the companion object of any sealed class of objects is annotated with @GenSealedEnum
, sealed-enum
will generate code that allows using the sealed class like an
enum. Extension properties are generated for the objects (ordinal
and name
), as well as the sealed class's companion object (values
, valueOf
). These extension properties are backed by an object
implementing SealedEnum
, which provides a generic interface that is more convenient that generically handling
normal enum classes.
Additional features include specifying the traversal order of sealed class hierarchies,
creating a SealedClass
object from normal enum classes, and generating isomorphic
enum classes for sealed enums.
How to use it.
0) Add dependencies to Gradle via Jitpack
Via kapt
:
plugins {
kotlin("kapt")
}
repositories {
maven(url = "https://jitpack.io")
}
dependencies {
implementation("com.github.livefront.sealed-enum:sealedenum:VERSION")
kapt("com.github.livefront.sealed-enum:sealedenumprocessor:VERSION")
}
Via ksp
:
plugins {
id("com.google.devtools.ksp") version "1.8.0-1.0.9"
}
repositories {
maven(url = "https://jitpack.io")
}
dependencies {
implementation("com.github.livefront.sealed-enum:runtime:0.7.0")
ksp("com.github.livefront.sealed-enum:ksp:0.7.0")
}
Check out the project on Github for the latest version information.
1) Annotate the companion object of a sealed class with @GenSealedEnum
sealed class Alpha {
object Beta : Alpha()
object Gamma : Alpha()
@GenSealedEnum
companion object
}
Use the generated extension methods:
println(Beta.ordinal) // 0
println(Alpha.values) // [Alpha$Beta@491cc5c9, Alpha$Gamma@74ad1f1f]
The SealedEnum
implementation can be retrieved with Alpha.sealedEnum
, and backs the other extensions properties and methods:
object AlphaSealedEnum : SealedEnum<Alpha> {
override val values: List<Alpha> = listOf(
Alpha.Beta,
Alpha.Gamma
)
override fun ordinalOf(obj: Alpha): Int = when (obj) {
Alpha.Beta -> 0
Alpha.Gamma -> 1
}
override fun nameOf(obj: AlphaSealedEnum): String = when (obj) {
Alpha.Beta -> "Alpha_Beta"
Alpha.Gamma -> "Alpha_Gamma"
}
override fun valueOf(name: String): AlphaSealedEnum = when (name) {
"Alpha_Beta" -> Alpha.Beta
"Alpha_Gamma" -> Alpha.Gamma
else -> throw IllegalArgumentException("""No sealed enum constant $name""")
}
}
Check out the project on Github for more detailed usage instructions.
Built by Livefront.
Livefront is a digital product consultancy. We're trusted by some of the world's most admired companies to drive strategy, design, and engineering for their core digital experiences. They partner with us to move faster, think bigger, and design products people love.
Learn more