Konvert
Konvert generates Kotlin mapper implementations with KSP. Kora makes the generated implementations ordinary components of the dependency container. For Java mapping, see MapStruct.
Konvert¶
Konvert generates Kotlin mappers with KSP.
Because it is a KSP processor it runs in the same compilation as Kora's own Kotlin processors, so Konvert is simply another ksp(...) dependency and needs no extra build wiring.
The Konvert extension is shipped inside io.koraframework:symbol-processors. It is registered through ServiceLoader and activates only when the io.mcarle.konvert.api.Konverter annotation type is resolvable on the classpath: in a project without Konvert it does nothing at all.
Dependency¶
Dependency in build.gradle.kts:
ksp("io.mcarle:konvert:4.5.1") //(1)!
ksp("io.koraframework:symbol-processors:2.0.0.RC2") //(2)!
implementation("io.mcarle:konvert-api:4.5.1") //(3)!
- The
KonvertKSPprocessor — it is the one that generates the mapper implementations (required, no default). - The Kora
KSPprocessors, which carry theKonvertextension (required, no default). - The
Konvertannotations,@Konverteramong them (required, no default).
As with MapStruct in Java, the Konvert versions are yours to choose: kora-bom constrains only io.koraframework:* artifacts.
Usage¶
Annotate an interface with @Konverter and declare the conversions as its methods:
data class Car(val make: String, val seatCount: Int)
data class CarDto(val make: String, val seatCount: Int)
@Konverter
interface CarMapper {
fun carToCarDto(car: Car): CarDto
}
Konvert generates a top-level object CarMapperImpl : CarMapper in the same package, and the Kora extension publishes that object in the graph under the CarMapper type.
You do not annotate the mapper with @Component and you do not import any module.
Renaming fields, computing values and any other per-property rule are expressed with Konvert's own annotations — see the Konvert documentation.
The injected mapper is an ordinary component:
@Component
class CarService(private val carMapper: CarMapper) {
fun convert(car: Car): CarDto {
return carMapper.carToCarDto(car)
}
}
Tag¶
A @Konverter may be qualified with a @Tag: declare the same tag on the mapper interface and at the injection point, and the mapper is provided exactly there.
@Tag(MyTag::class)
@Konverter
interface CarMapper {
fun carToCarDto(car: Car): CarDto
}
@Component
class CarService(@Tag(MyTag::class) private val carMapper: CarMapper)
Limitations¶
@Konverteris recognised on an interface only. An abstract class annotated with@Konverteris not provided by the extension.- The generated implementation is a Kotlin
object, so it has no constructor and cannot receive anything from the graph. A mapper that needs a collaborator has to be written as a regular @Component that delegates to the generatedCarMapperImplobject. - The implementation is looked up as
<SimpleName>Implin the mapper's own package. For a@Konverternested inside another typeKonvertstill generates a top-level object and drops the enclosing type name, so the lookup drops it as well.
Errors¶
Generated Konvert implementation was not found(followed byexpected type: <package>.<Name>Impl) — the graph asked for a@Konvertertype, but the generated object does not exist. Either theKonvertKSPprocessor is not declared in this module, orKonvertfailed earlier in the same compilation and printed its own errors above this one. Fix the first reported error and rebuild.