Last active
July 28, 2019 11:04
-
-
Save bmc/6d7b16a7634a6f93e8619dcb40efe8b2 to your computer and use it in GitHub Desktop.
Read a CSV-like, pipe-delimited (jar) resource into Person records, via FS2
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
import scala.concurrent.Future | |
import scala.concurrent.ExecutionContext.Implicits.global | |
import java.util.Date | |
import java.text.SimpleDateFormat | |
import fs2._ | |
// id and gender should really be more strongly-typed, but | |
// this is just a demo... | |
case class Person(id: Int, | |
firstName: String, | |
middleName: String, | |
lastName: String, | |
gender: String, | |
birthDate: Date, | |
ssn: String, | |
salary: Int) | |
object Thingie { | |
/** Using fs2.io, read a pipe-delimited text file of | |
* people from a classpath resource. | |
* | |
* @param resource the name of the resource | |
* | |
* @return a Future of a Map of (id -> Person). | |
*/ | |
def readPeople(resource: String): Future[Map[Int, Person]] = { | |
val cl = this.getClass.getClassLoader | |
val df = new SimpleDateFormat("yyyy-MM-dd") | |
Option(cl.getResourceAsStream(resource)).map { is => | |
io.readInputStream[Task](Task.now(is), 16 * 1024) | |
.through(text.utf8Decode) | |
.through(text.lines) | |
.drop(1) // drop file header | |
.filter { line => !line.trim().isEmpty } | |
.zipWithIndex | |
.map { case (line, i) => | |
line.split("""\|""") match { | |
case Array(fn, mn, ln, gender, birthDate, salary, ssn) => | |
val id = i + 1 | |
(id, Person(id = id, | |
firstName = fn, | |
middleName = mn, | |
lastName = ln, | |
gender = gender, | |
birthDate = df.parse(birthDate), | |
salary = salary.toInt, | |
ssn = ssn)) | |
case _ => | |
throw new Exception(s"""Line ${i+1}: CSV parse error: "$line"""") | |
} | |
} | |
.runLog | |
.unsafeRunAsyncFuture() | |
.map(_.toMap) | |
} | |
.getOrElse(Future.failed(new Exception(s"Unable to load resource $resource"))) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment