KMapperWrapper
Chooses the RETURN SHAPE of a generated mapper — @MapTo(X::class, wrapper = …) / @MapFrom(X::class, wrapper = …).
Every mapping always generates the plain core fun Source.toX(): X, which throws a MappingException on a hard failure. A wrapper adds extra extension(s) on top of it, one per wrap overload, named to{Target}{suffix} — e.g. KtResult adds fun Source.toXResult(): Result<X>. Nested mappings always call the plain core, so wrappers never affect how mappers compose.
Default — use the module-wide setting (Gradle
KMapper { wrapper = … }or the KSP optionkmapper.wrapper); when nothing is configured this is None.None — only the plain
toX().KtResult — also
toXResult(): Result<X>.Flow — also
toXFlow(): Flow<X>, for both a single value and aFlowof sources.
Writing your own wrapper
The built-ins use no privileged mechanism — a user wrapper is written exactly the same way: an object implementing KMapperWrapper, annotated with WrapperSuffix, with one or more public wrap functions of the shape
fun <S, T> wrap(source: <R in terms of S>, map: (S) -> T): <W in terms of T>For each wrap overload the compiler generates fun R<Source>.to{Target}{suffix}(…externals): W<Target> = YourWrapper.wrap(this) { it.to{Target}(…externals) }.
@WrapperSuffix("Either")
object EitherWrapper : KMapperWrapper {
fun <S, T> wrap(source: S, map: (S) -> T): Either<Throwable, T> = Either.catch { map(source) }
}
@MapTo(UserDomain::class, wrapper = EitherWrapper::class) // → toUserDomainEither()
data class UserDto(...)Inheritors
Types
Resolves to the module-wide setting (Gradle KMapper { wrapper = … }), else None.
Adds two toXFlow() overloads: Source.toXFlow(): Flow<X> (a cold single-value flow — the mapping runs, and may throw, on collection) and Flow<Source>.toXFlow(): Flow<X> (maps every emitted source).
Adds toXResult(): Result<X> — hard failures become Result.failure.
No wrapper: only the plain toX(): X is generated.