Вы можете использовать составной интерфейс для достижения этой цели, поскольку вы не можете написать один класс конвертера для нескольких типов объектов. Это отчасти хакерство, но может сработать:
interface BaseType {
val arg0: String
fun asString() : String? {
return when(this) {
is TypeA -> "${TypeA::class.simpleName}$separatorParam$arg0"
is TypeB -> "${TypeB::class.simpleName}$separatorParam$arg0"
else -> null
}
}
companion object {
const val separatorParam = "::"
}
}
enum class TypeA (override val arg0: String) : BaseType {
A_ONE("argument 1"),
A_TWO("argument 2");
companion object {
fun getValueTypes(arg0: String) : TypeA? = values().firstOrNull { it.arg0 == arg0 }
}
}
enum class TypeB (override val arg0: String) : BaseType {
A_ONE("argument 1"),
A_TWO("argument 2");
companion object {
fun getValueTypes(arg0: String) : TypeB? = values().firstOrNull { it.arg0 == arg0 }
}
}
class Converter {
@TypeConverter
fun fromBaseType(type: BaseType) : String? = type.asString()
@TypeConverter
fun toBaseType(param: String?) : BaseType? = param?.asBaseType()
private fun String.asBaseType() : BaseType? {
val stringArray = this.split(BaseType.separatorParam)
val className : String? = stringArray[0]
return when(className) {
TypeA::class.simpleName -> TypeA.getValueTypes(stringArray[1])
TypeB::class.simpleName -> TypeB.getValueTypes(stringArray[1])
else -> null
}
}
}
Тогда вам нужна функция в вашем data class
, чтобы предоставить вам фактический TypeA или TypeB
data class MyDbModel(val baseType: BaseType) {
inline fun <reified T: BaseType> getTypeAs() : T? =
when(baseType) {
is TypeA -> TypeA.getValueTypes(baseType.arg0) as? T
is TypeB -> TypeB.getValueTypes(baseType.arg0) as? T
else -> null
}
}
fun foo() {
val model = MyDbModel(TypeA.A_ONE)
val type = model.getTypeAs<TypeA>()
}
Недостатком этого является то, что он работает только для уникального arg0
в пределах определенного перечисления, для этого вы можете использовать порядковый номер или вы можете использовать сгенерированный идентификатор, такой как R.id.a_one
, в качестве первого параметра, а затем второй параметр может быть вашим строка.