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 } }