Enum Mapping¶
Kraft generates exhaustive when expressions to map between enum classes. Every source entry must be accounted for, either by automatic name matching or by explicit field mappings.
@MapEnum¶
Place @MapEnum on a config object (class or object). Both source and target must reference enum classes -- using a non-enum class produces a compile-time error.
Parameters:
| Parameter | Description |
|---|---|
source |
The enum class to map from |
target |
The enum class to map to |
fieldMappings |
Array of FieldMapping for entries with different names (default: empty) |
aliasEmitMode |
Per-mapper alias-emission override (AliasEmitMode.INHERIT by default). See Side Aliases — Per-Mapper Override. |
When you do NOT need @MapEnum¶
Kraft auto-generates an enum mapper at compile time when all of these hold:
- The source and target enum types are both declared in the current module (i.e. KSP is processing both files this round).
- The pair is reachable from at least one declared
@MapConfig/@MapToparent — directly as a property type, transitively through any nested data-class properties, or throughList<…>/Set<…>element positions. Intermediate data classes do NOT need their own@MapConfig. - Both property occurrences are non-nullable (
Status, notStatus?). - Every source-enum entry has a same-named target-enum entry. Extra entries on the target are fine.
When all four conditions hold the parent mapper compiles without any
@MapEnum declaration, and the auto-derived mapper is also published as a
@KraftConverterDelegate so downstream modules can import it. If the
parent has @MapReverse, both directions auto-derive when the by-name
pairing also succeeds in reverse.
If any of the conditions does not hold (cross-module pair, mismatched
entry names, nullable properties, custom fieldMappings), declare
@MapEnum explicitly — Kraft will not silently guess.
Auto-Mapping¶
When all entries share the same name on both sides, no fieldMappings are needed. Kraft matches entries by name automatically.
enum class Status { ACTIVE, INACTIVE, BANNED }
enum class StatusDto { ACTIVE, INACTIVE, BANNED }
@MapEnum(source = Status::class, target = StatusDto::class)
object StatusMapping
Generated code:
fun Status.toStatusDto(): StatusDto = when (this) {
Status.ACTIVE -> StatusDto.ACTIVE
Status.INACTIVE -> StatusDto.INACTIVE
Status.BANNED -> StatusDto.BANNED
}
Custom Entry Mapping¶
Use fieldMappings when source and target entries have different names. Each FieldMapping maps one source entry name to one target entry name.
enum class Status { ACTIVE, DISABLED }
enum class StatusDto { ACTIVE, INACTIVE }
@MapEnum(
source = Status::class,
target = StatusDto::class,
fieldMappings = [FieldMapping(source = "DISABLED", target = "INACTIVE")]
)
object StatusMapping
Generated code:
fun Status.toStatusDto(): StatusDto = when (this) {
Status.ACTIVE -> StatusDto.ACTIVE
Status.DISABLED -> StatusDto.INACTIVE
}
Mixed Mapping¶
Auto-matched entries and custom field mappings coexist naturally. Entries that share a name are mapped automatically; entries that differ are covered by fieldMappings.
enum class PaymentState { PAID, PENDING, FAILED }
enum class PaymentStatus { PAID, AWAITING, ERROR }
@MapEnum(
source = PaymentState::class,
target = PaymentStatus::class,
fieldMappings = [
FieldMapping(source = "PENDING", target = "AWAITING"),
FieldMapping(source = "FAILED", target = "ERROR")
]
)
object PaymentMapping
Generated code:
fun PaymentState.toPaymentStatus(): PaymentStatus = when (this) {
PaymentState.PAID -> PaymentStatus.PAID
PaymentState.PENDING -> PaymentStatus.AWAITING
PaymentState.FAILED -> PaymentStatus.ERROR
}
PAID is auto-mapped by name, while PENDING and FAILED use their explicit mappings.
Exhaustiveness¶
Every source entry must be accounted for -- either by automatic name matching or by an explicit FieldMapping. If any source entry is left unmapped, Kraft emits a compile-time error.
Example: unmapped entry¶
enum class Flag { A, B, C }
enum class FlagDto { A, B } // C has no match and no fieldMappings entry
@MapEnum(source = Flag::class, target = FlagDto::class)
object FlagMapping
This produces a compile-time KSP error indicating "unmapped source entries", listing which entries need to be covered.
Error Cases¶
| Condition | Result |
|---|---|
| Source or target is not an enum class | Compile-time error |
A source entry has no matching target entry and no FieldMapping |
Compile-time error ("unmapped source entries") |
A FieldMapping references a source entry name that does not exist |
Compile-time error |
A FieldMapping references a target entry name that does not exist |
Compile-time error |