ursus
11/04/2021, 7:21 PMclass BusinessMessageIdColumnAdapter : ColumnAdapter<BusinessMessageId, String> {
override fun decode(databaseValue: String): BusinessMessageId = BusinessMessageId(databaseValue)
override fun encode(value: BusinessMessageId): String = value.value
}
for every type of id, which is annoying
I know I could get it via reflection, but .. probably looking for a "hack" like this (the enumValues function)
@Suppress("FunctionName") // Emulating a constructor.
inline fun <reified T : Enum<T>> EnumColumnAdapter(): EnumColumnAdapter<T> {
return EnumColumnAdapter(enumValues())
}
ephemient
11/05/2021, 12:20 AMclass EnumColumnAdapter<T : Enum<T>>(private val javaClass: Class<T>) {
fun decode(databaseValue: String): T = java.lang.Enum.valueOf(javaClass, databaseValue)
fun encode(value: T): String = value.name
}
EnumColumnAdapter(BusinessMessageId::class.java) // etc.
ephemient
11/05/2021, 12:21 AMclass EnumColumnAdapter<T : Enum<T>> @PublishedApi internal constructor(
private val valuesByName: Map<String, T>
) {
fun decode(databaseValue: String): T = valuesByName.getValue(databaseValue)
fun encode(value: T): String = value.name
}
inline fun <reified T : Enum<T>> EnumColumnAdapter(): EnumColumnAdapter<T> =
EnumColumnAdapter(valuesByName = enumValues<T>().associateBy { it.name })
EnumColumnAdapter<BusinessMessageId>() // etc.
ephemient
11/05/2021, 12:22 AMJonathan Mew
11/05/2021, 8:59 AMursus
11/05/2021, 2:07 PMursus
11/05/2021, 2:10 PMJonathan Mew
11/05/2021, 2:35 PMhow do you instantiate it back from stringcould you give me an example, please?
ursus
11/05/2021, 2:53 PMephemient
11/05/2021, 7:07 PMephemient
11/05/2021, 7:09 PMephemient
11/05/2021, 7:13 PMclass ColumnAdapter<T>(
private val encode: (String) -> T,
private val decode: (T) -> String,
)
ColumnAdapter(
encode = ::BusinessMessageId,
decode = BusinessMessageId::value,
)
but you can't get a ::T
constructor for a generic type <T>
, so that's about as far as you can goursus
11/05/2021, 8:08 PMJonathan Mew
11/05/2021, 11:25 PMclass EmailAddressColumnType : StringMicrotypeColumnType<EmailAddress>() {
override fun fromString(s: String) = EmailAddress(s)
}
A decent bit of logic is still shared, but not as neat as you're afterephemient
11/06/2021, 12:29 AM@JvmInline
value class Id(val value: String)
val converter = Converter<Id>()
println(converter.encode(Id("Hello, ")) + converter.decode("world!"))
// => Hello, Id(value=world!)
ephemient
11/06/2021, 12:33 AMId
doesn't come into play at all: when generic, you're dealing with the class Id
, not the underlying String
representation, just like how <T : Int>
is also always boxedursus
11/07/2021, 10:13 AM