Mam plik CSV który zawiera listę rekordów z danymi. Napisałem sobie parser (w Kotlinie ale to akurat nie ma znaczenia bo w Javie można zrobić podobnie) który wczytuje te dane a następnie przepisuje na listę objektów klasy Transaction
:
class Transaction(
val transactionDateTime: LocalDateTime,
val type: TransactionType,
val amount: BigDecimal,
val currency: Currency,
)
Metoda która parsuje rekord zwaca Either
i wygląda mniej więcej tak:
fun getTransaction(rawRow: Row): Either<ParserError, Transaction> {
return Try { buildTransaction(rawRow) }
.toEither(AppError(ErrorReason.COULD_NOT_PARSE_ROW, rawRow.toRawString()))
}
private fun buildTransaction(rawRow: Row): Transaction {
return TransactionBuilder(
transactionDateTime = getDateTime(rawRow),
type = getTransactionType(rawRow),
amount = getAmount(rawRow),
currency = getCurrency(rawRow),
)
Jeśli któraś z metod parsujących się wysypie (np błędny format daty itp) to rzucam Left'em z błędem + info który to rekord. Wszystko fajnie funkcjonuje ale:
- Nie mam pojęcia która komórka była błędna (znam tylko pełny rekord)
- Okazuje się że pewne dane są mniej potrzebne i nawet jeśli nie powiedzie się wczytanie jakiejś komórki to można ją pominąć (np. date transakcji).
Zastanawiam się więc jak to sensownie zrobić i nic mi ciekawego do głowy nie przychodzi. Pomyślałem sobie że może moje metody parsujące kolumny (getDateTime
itd) powinny zwracać Try<LocalDateTime>
i później ewentualnie zweryfikować które się powiodły które nie natomiast nie widzę w ogóle jak to mogłoby być sensownie zaimplementowane bo nie chciałbym potem robić czegoś takiego typu if(getDateTime(rawRow).isFailure)
to pomiń tę komórkę a jeśli if(getAmount(rawRow).isFailure)
to rzuć Leftem. Takie trochę słabe rozwiązanie. Ma ktoś może pomysł jak to sensowniej ugryźć?