Last active
February 25, 2018 12:56
-
-
Save Pooh3Mobi/bd1515dd8c72a519fbf962ed1eaf51e8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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