🎲 Kotlin Symbol Processor to auto-generate extensive sealed classes and interfaces for Android and Kotlin.

Overview

SealedX


License API Build Status Android Weekly Profile


🎲 Kotlin Symbol Processor to auto-generate extensive sealed classes and interfaces for Android and Kotlin.

Why SealedX?

SealedX generates extensive sealed classes & interfaces based on common sealed classes for each different model. You can reduce writing repeated sealed classes for every different model by auto-generating based on KSP (Kotlin Symbol Processor).

You can massively reduce writing repeated files such as _UiState sealed interfaces if your project is based on MVI architecture.

Use Cases

If you want to learn more about how to migrate and use cases, check out the repositories below:

Gradle Setup

To use KSP (Kotlin Symbol Processing) and SealedX library in your project, you need to follow steps below.

1. Enable KSP in your module

Add the KSP plugin below into your module's build.gradle file:

Kotlin (KTS)
plugins {
    id("com.google.devtools.ksp") version "1.7.10-1.0.6"
}
Groovy
plugins {
    id("com.google.devtools.ksp") version "1.7.10-1.0.6"
}

Note: Make sure your current Kotlin version and KSP version is the same.

2. Add SealedX dependencies

Maven Central

Add the dependency below into your module's build.gradle file:

dependencies {
    implementation("com.github.skydoves:sealedx-core:1.0.0")
    ksp("com.github.skydoves:sealedx-processor:1.0.0")
}

3. Add KSP source path

To access generated codes from KSP, you need to set up the source path like the below into your module's build.gradle file:

Android Kotlin (KTS)
kotlin {
  sourceSets.configureEach {
    kotlin.srcDir("$buildDir/generated/ksp/$name/kotlin/")
  }
}
Android Groovy
android {
    applicationVariants.all { variant ->
        kotlin.sourceSets {
            def name = variant.name
            getByName(name) {
                kotlin.srcDir("build/generated/ksp/$name/kotlin")
            }
        }
    }
}
Pure Kotlin (KTS)
kotlin {
    sourceSets.main {
        kotlin.srcDir("build/generated/ksp/main/kotlin")
    }
    sourceSets.test {
        kotlin.srcDir("build/generated/ksp/test/kotlin")
    }
}
Pure Kotlin Groovy
kotlin {
    sourceSets {
        main.kotlin.srcDirs += 'build/generated/ksp/main/kotlin'
        test.kotlin.srcDirs += 'build/generated/ksp/test/kotlin'
    }
}

Usage

ExtensiveSealed

@ExtensiveSealed annotation is the main trigger of the Kotlin Symbol Processor to run a sealed-extensive processor on compile time.

  • @ExtensiveSealed must be annotated to sealed classes or interfaces, which should be a common model to generate extensive sealed classes and interfaces.
  • @ExtensiveSealed receives an array of @ExtensiveModel annotations, which include the extensive model types.
  • If you build your project, extensive sealed classes or interfaces will be generated based on those extensive models.

Let's see a common UiState sealed interface below that is annotated with @ExtensiveSealed annotation:

@ExtensiveSealed(
  models = [
    ExtensiveModel(Poster::class),
    ExtensiveModel(PosterDetails::class)
  ]
)
sealed interface UiState {
  data class Success(val data: Extensive) : UiState
  object Loading : UiState
  object Error : UiState
}

The example codes above will generate PosterUiState and PosterDetailsUiState sealed interfaces below:

PosterUiState (generated):

public sealed interface PosterUiState {
  public object Error : PosterUiState

  public object Loading : PosterUiState

  public data class Success(
    public val `data`: Poster,
  ) : PosterUiState
}

PosterDetailsUiState (generated):

public sealed interface PosterDetailsUiState {
  public object Error : PosterDetailsUiState

  public object Loading : PosterDetailsUiState

  public data class Success(
    public val `data`: PosterDetails,
  ) : PosterDetailsUiState
}
See further sealed class examples

In the case of the sealed classes, it's not different fundamentally from sealed interface examples.

@ExtensiveSealed(
  models = [ ExtensiveModel(type = Poster::class) ]
)
sealed class UiState {
  data class Success(val data: Extensive) : UiState()
  object Loading : UiState()
  object Error : UiState()
}

The example codes above will generate the PosterUiState sealed class below:

PosterUiState (generated):

public sealed class PosterUiState {
  public object Error : PosterUiState()

  public object Loading : PosterUiState()

  public data class Success(
    public val `data`: Poster,
  ) : PosterUiState()
}

ExtensiveModel

@ExtensiveModel annotation class contains information on extensive models like model type and a custom name, which decides the name of generated classes. Basically, (the simple name of the type) + (the name of common sealed classes) will be used to name of generated classes, but you can modify the prefix with the name parameter like the example below:

@ExtensiveSealed(
  models = [ ExtensiveModel(type = PosterExtensive::class, name = "Movie") ]
)
sealed interface UiState {
  data class Success(val data: Extensive) : UiState
  object Loading : UiState
  object Error : UiState
}

The example codes above will generate MovieUiState file instead of PosterExtensiveUiState like the below:

MovieUiState (generated):

public sealed interface MovieUiState {
  public object Error : MovieUiState

  public object Loading : MovieUiState

  public data class Success(
    public val `data`: PosterExtensive,
  ) : MovieUiState
}

Collection type in @ExtensiveModel

Basically, you can't set a collection type like a List to the type parameter of the @ExtensiveModel annotation. So if you need to set a collection type as an extensive model, you need to write a wrapper class like the below:

data class PosterExtensive(
  val posters: List<Poster>
)

@ExtensiveSealed(
  models = [ ExtensiveModel(type = PosterExtensive::class) ]
)
sealed interface UiState {
    ..
}

Extensive

Extensive is an interface that is used to represent extensive model types of sealed classes and interfaces. When you need to use an extensive model type in your primary constructor of data class, you can use the Extensive extensive type on your common sealed classes and interfaces. It will be replaced by the extensive model type on compile time.

@ExtensiveSealed(
  models = [ ExtensiveModel(type = PosterExtensive::class) ]
)
sealed interface UiState {
  // You need to use the Extensive type if you want to use an extensive model type in the generated code.
  data class Success(val data: Extensive) : UiState
  ..
}

The example codes above will generate PosterExtensiveUiState sealed interface like the below:

PosterExtensiveUiState (generated):

public sealed interface PosterExtensiveUiState {
  public object Error : PosterExtensiveUiState

  public object Loading : PosterExtensiveUiState

  public data class Success(
    public val `data`: PosterExtensive,
  ) : PosterExtensiveUiState
}

As you can see from the example above, the Extensive interface type will be replaced with the extensive model by the SealedX processor on compile time.

Find this repository useful? ❤️

Support it by joining stargazers for this repository.
Also, follow me on GitHub for my next creations! 🤩

License

Designed and developed by 2022 skydoves (Jaewoong Eum)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
You might also like...
Simple Kotlin application that displays the currently available network interfaces on your machine

Network-Interface-Checker Simple Kotlin application that displays the currently available network interfaces on your machine. An executable jar can be

Event State Processor Generator plugin is compatible with IntelliJ and Android Studio.
Event State Processor Generator plugin is compatible with IntelliJ and Android Studio.

Event State Processor Generator plugin is compatible with IntelliJ and Android Studio. It provides source code generation for the EventStateProcessor Library to increase code productivity in Flutter apps development.

An annotation processor library that automatically creates Hilt's `@Binds` functions and modules.
An annotation processor library that automatically creates Hilt's `@Binds` functions and modules.

HiltBinder An annotation processor library that automatically creates Hilt's @Binds functions and modules. If you think this library is useful, please

KSP annotation processor for Toothpick

toothpick-ksp KSP annotation processor for Toothpick. All credits go to olivierperez/ksp for the initial work on a KSP processor. Bear in mind this is

Kafka Streams Processor to unwrap CØSMOS blocks into CØSMOS transactions
Kafka Streams Processor to unwrap CØSMOS blocks into CØSMOS transactions

Kafka Processor CØSMOS-Block A Kafka Streams Processor to unwrap CØSMOS blocks into CØSMOS transactions. Purpose The Kafka Processor CØSMOS-Block is b

Small kotlin library for persisting _single instances_ of kotlin data classes
Small kotlin library for persisting _single instances_ of kotlin data classes

PerSista Small library for persisting single instances of kotlin data classes. NB: PerSista uses typeOf() internally which is marked as @ExperimentalS

An AutoValue extension that generates binary and source compatible equivalent Kotlin data classes of AutoValue models.
An AutoValue extension that generates binary and source compatible equivalent Kotlin data classes of AutoValue models.

AutoValue Kotlin auto-value-kotlin (AVK) is an AutoValue extension that generates binary-and-source-compatible, equivalent Kotlin data classes. This i

Camunda Platform 7 WebApp Auto-Login

Camunda Platform 7 WebApp Auto-Login Auto-login feature for development Why should you use it? Because otherwise, you need to type again and again "ad

A Kotlin library used to analyse discrete Markov chains, in order to generate plausible sequences

Markov Markov is a Kotlin library used to analyse discrete Markov chains, in order to generate plausible sequences. Using This project is still under

Releases(1.0.0)
  • 1.0.0(Aug 12, 2022)

    🎉 SealedX version 1.0.0 was published! 🎉

    🎲 SealedX is a Kotlin Symbol Processor to auto-generate extensive sealed classes and interfaces.

    Source code(tar.gz)
    Source code(zip)
Owner
Jaewoong Eum
Android Developer Advocate @GetStream 🥑 • GDE for Android • Open Source Software Engineer ❤️ • Love coffee, music, magic tricks, and writing poems.
Jaewoong Eum
Kotlin Symbol Processor library to create Mutable and Immutable variants of objects.

implier Kotlin Symbol Processor plugin to create Mutable and Immutable variants of objects. Examples @ImmutableImpl @MutableImpl public interface Samp

Vadim Yaroschuk 13 Jul 27, 2022
glide's ksp compiler ,use kotlin symbol processor

glide-ksp glide's ksp compiler ,use kotlin symbol processor requirements library version kotlin >= 1.6.10 ksp 1.6.10-1.0.2 usage add jitpack repositor

Mistletoe 23 Jul 6, 2022
Clean MVVM with eliminating the usage of context from view models by introducing hilt for DI and sealed classes for displaying Errors in views using shared flows (one time event), and Stateflow for data

Clean ViewModel with Sealed Classes Following are the purposes of this repo Showing how you can remove the need of context in ViewModels. I. By using

Kashif Mehmood 23 Sep 16, 2022
An extensive collection of Kotlin Android Utils

An extensive collection of Kotlin Android Utils This library contains small helper functions used throughout almost all of my other projects. The goal

Allan Wang 201 Aug 28, 2022
Extensive Redis Pub-Sub wrapper for lettuce written in Kotlin

aware Extensive annotation-based Redis Pub-Sub wrapper for lettuce written in Kotlin. Aware was written to be a replacement for the very dated Banana

Subham 3 Jul 17, 2022
Mocking for Kotlin/Native and Kotlin Multiplatform using the Kotlin Symbol Processing API (KSP)

Mockative Mocking for Kotlin/Native and Kotlin Multiplatform using the Kotlin Symbol Processing API (KSP). Installation Mockative uses KSP to generate

Mockative 100 Sep 24, 2022
BindsAdapter is an Android library to help you create and maintain Adapter class easier via ksp( Kotlin Symbol Processing).

BindsAdapter BindsAdapter is an Android library to help you create and maintain Adapter class easier via ksp( Kotlin Symbol Processing). Installation

Jintin 5 Jul 30, 2022
Exploring Kotlin Symbol Processing - KSP. This is just an experiment.

KSP example Exploring Kotlin Symbol Processing - KSP. This is just an experiment. Project contains 2 modules Processing Example Processing module is t

Merab Tato Kutalia 12 Aug 23, 2022
Kotlin Symbol Processing (KSP) sample project

Kotlin Symbol Processing (KSP) Sample Project Sample annotation processor created with Kotlin Symbol Processing (KSP) API. The repository supplements

Pavlo Stavytskyi 30 Sep 12, 2022
Jetpack Compose for Desktop and Web, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.

Jetpack Compose for Desktop and Web, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.

JetBrains 9.4k Sep 25, 2022