Esa
11/12/2019, 8:24 AM.csv
-file, and want to be as explicit as possible.
The file comes in a strict format, and I am able to say for sure what content-type each column will have. For this reason, I want to model it explicitly, like so:
sealed class CsvField {
data class ExternalId(val value: String) {
companion object {
const val index: Int = 0
}
}
}
So obviously there will be many more columns, which means the sealed class ends up looking extremely verbose when every data class has its own companion object, and there are like 15 of them.
So back to my question; when my intent is to have 1 subclass of a sealed class with 1 constant, unchangeable field and one specified in constructor, is this the best way? Or am I missing something obvious? Is there a better pattern here? I tried with enum class
first, but that way I don’t get to specify the value of the field, only the expected data. I could have a data class with the enum as type, and a plain string as value, but idk. Thoughts?karelpeeters
11/14/2019, 11:07 AMEsa
11/14/2019, 11:18 AMNAME;SURNAME;ID;EMAIL
Ted;Jamesson;1;some@email.net
Joe;Johnsson;2;some@invalid@email.net
This would be parsed as 2x4 CsvField-subclasses, with one subclass per column.Esa
11/14/2019, 11:19 AMfun validate(csvField: CsvField)
that contains the logic to determine if a provided string value per column is valid or not, such as a regex to filter out the invalid email in the bottom row.karelpeeters
11/14/2019, 11:24 AMEsa
11/14/2019, 11:25 AMEsa
11/14/2019, 11:27 AMfun validate(csvField: CsvField) {
when (csvField) {
is Name -> validateByName(csvField.value)
is Email -> validateByEmail(csvField.value)
}
}
Something like this is what I wantEsa
11/14/2019, 11:27 AMkarelpeeters
11/14/2019, 11:28 AMEsa
11/14/2019, 11:28 AMval validData = csvValues.all { validate(it) }
if (validData) {
proceedWithTask()
}
Esa
11/14/2019, 11:28 AMkarelpeeters
11/14/2019, 11:30 AMEsa
11/14/2019, 11:34 AMEsa
11/14/2019, 11:34 AMCsvField
to DomainObject?
happenskarelpeeters
11/14/2019, 11:38 AMEsa
11/14/2019, 1:03 PMkarelpeeters
11/14/2019, 4:45 PMclass CsvData(val columns: List<Column>, val data: List<List<String>>) {
fun verify() {
for (row in data) {
check(columns.size == row.size)
for ((col, value) in (columns zip row))
col.verify(value)
}
}
}
interface Column {
fun verify(value: String)
}
class RegexColumn(val regex: Regex): Column {
override fun verify(value: String) {
check(regex.matchEntire(value) != null)
}
}
Matteo Mirk
11/20/2019, 1:51 PM