Skip to content

Instantly share code, notes, and snippets.

@Pooh3Mobi
Last active February 25, 2018 12:56
Show Gist options
  • Save Pooh3Mobi/bd1515dd8c72a519fbf962ed1eaf51e8 to your computer and use it in GitHub Desktop.
Save Pooh3Mobi/bd1515dd8c72a519fbf962ed1eaf51e8 to your computer and use it in GitHub Desktop.
sealed class Row {
data class Header(
val columns: List<String>
) : Row()
data class Item(
val id: Long,
val name: String,
val price: Long?
) : Row()
}
interface Parser {
fun parse(content: String): List<Row>
class IllegalFormatException(override val message: String) : Exception(message)
}
class CSVParser : Parser {
override fun parse(content: String): List<Row> {
val rows = content.split(System.getProperty("line.separator"))
val header = rows.getOrNull(0)
?.let { Row.Header(it.split(",")) }
?: throw Parser.IllegalFormatException("no header at row 1")
val items = rows.drop(1)
.mapIndexed { index, s ->
val l = s.split(",")
val id = l.getOrThrow(0, { "there are no 'id' at ${index + 1}"})
.toLongOrThrow { "${index + 1} is not a number: $it" }
val name = l.getOrThrow(1, {"there are not 'name' at ${index + 1} "})
val price = l.getOrNull(2)?.toLongOrNull()
Row.Item(id, name, price)
}
return listOfNotNull(header) + items
}
}
private inline fun List<String>.getOrThrow(index: Int, lazyMessage: () -> String): String {
return this.getOrElse(index, { throw Parser.IllegalFormatException(lazyMessage())})
}
private inline fun String.toLongOrThrow(radix: Int = 10, lazyMessage: (String) -> String): Long {
try {
return toLong(radix)
} catch (e: NumberFormatException) {
throw Parser.IllegalFormatException(lazyMessage(this))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment