Example for custom type converters
b-heimann-senacor opened this issue · 2 comments
Could you provide instructions on how to register a custom type converter, e.g. to convert a String to a Currency field?
@KonvertTo(Account::class)
data class AccountDto(val amount: String, val currency: String)
data class Account(val amount: String, val currency: java.util.Currency)
class StringToCurrencyConverter : BaseTypeConverter(String::class, java.util.Currency::class) {
override fun convert(fieldName: String, nc: String): String =
"$fieldName$nc.let·{ java.util.Currency.getInstance(it) }"
}
According to the documentation, the type converter must be on the KSP classpath: https://mcarleio.github.io/konvert/modules.html#to-extend-the-functionality-of-konvert-the-following-modules-are-provided
- konvert-converter-api
This module can be used to build your own TypeConverters to be used by Konvert during compilation. As Konvert is using SPI, >you can build your own library and just include it into KSP classpath! (TODO: reference example)
How can I do this?
Also, is it possible to enable one of the provided TypeConverters globally, that is not enabled by default?
E.g. String -> BigDecimal TypeConverter,
Ok, so regarding TypeConverter:
- If you just need a custom TypeConverter for one single project, you probably do not need to write a "real"
TypeConverer
. Instead, you can do the following:
@Konverter
interface MyCustomConverter {
fun stringToCurrency(str: String): Currency {
return Currency.getInstance(str)
}
}
Konvert registers all @KonverTo
, @KonvertFrom
and @Konvert
/@Konverter
functions as TypeConverter
s during KSP run. It even works between multiple modules, e.g. when you have a module A where you define the MyCustomConverter
and a module B which depends on module A where you have a mapping from String->Currency, then Konvert knows the MyCustomConverter
and will use it.
@KonvertTo(Target::class)
data class Source(val currency: String)
data class Target(val currency: Currency)
Konvert will then generate something like this:
import io.mcarle.konvert.api.Konverter
public fun Source.toTarget(): Target = Target(
currency = Konverter.get<MyCustomConverter>().stringToCurrency(str = currency)
)
-
If you nevertheless need or want to build a custom
TypeConverter
so that you can use it in various projects, have more control on the generated code, or want to map differently than konvert does, or you do not want to have a dependency on konvert in runtime: Have a look at theconverter
module of konvert. It is exactly what you have to build. I will document it in the future. -
Regarding enabling
TypeConverter
s globally, there is no such configuration yet. But it is planned to do so. For now, you either have to enable it per Mapping, or you can write your own String->BigDecimal function as shown in 1.
Thank you, the first option works fine.