Skip to content

Instantly share code, notes, and snippets.

@non
Last active November 5, 2020 03:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save non/145a615134983e71e0b712fcaae315de to your computer and use it in GitHub Desktop.
Save non/145a615134983e71e0b712fcaae315de to your computer and use it in GitHub Desktop.
package cats.parse
package examples
import cats.implicits._
import Parser.{char, charWhere, charsWhile, string1}
object Csv {
def mkString(p: Parser1[Char]): Parser[String] =
p.rep.map(_.mkString)
val parser: Parser[Vector[Vector[String]]] = {
val quote: Parser1[Unit] = char('"')
val notQuote: Parser1[Char] = charWhere(_ != '"')
val escapedQuote: Parser1[Char] = string1("\"\"").as('"')
val standardField: Parser[String] =
charsWhile(c => c != '"' && c != ',').string
val quotedField : Parser[String] =
quote *> mkString(notQuote orElse1 escapedQuote) <* quote
val field: Parser[String] =
quotedField orElse standardField
val row: Parser[Vector[String]] =
(field ~ (quote *> field).rep).map { case (x, xs) => (x :: xs).toVector }
val lineBreak: Parser1[Unit] =
string1("\r\n") orElse1 char('\n')
val rows: Parser[Vector[Vector[String]]] =
(row.with1 <* lineBreak).rep.map(_.toVector)
rows
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment