<commit_before>package com.nrinaudo.csv

import simulacrum.{noop, typeclass}

/** Typeclass used to decode the content of a single CSV cell.
  *
  * Standard types are already provided for in the companion object.
  *
  * See also the companion class, {{{CellEncoder}}}, as well as {{{RowDecoder}}}, used to read wholes rows.
  */
@typeclass trait CellDecoder[A] {
  /** Turns the content of a CSV cell into an {{{A}}}. */
  @noop def decode(s: String): Option[A]

  @noop def decode(ss: Seq[String], index: Int): Option[A] =
    if(ss.isDefinedAt(index)) decode(ss(index))
    else                      None

  /** Creates a new {{{CellDecoder}}} that applies the specified function to the result of {{{read}}}.
    *
    * This can be useful if you just need a {{{CellDecoder}}} implementation that specialises an existing type - to add
    * a scalaz tag, say.
    */
  @noop def map[B](f: A => B): CellDecoder[B] = CellDecoder(s => decode(s).map(f))
}

/** Provides default implementations and construction methods for {{{CellDecoder}}}. */
object CellDecoder {
  /** Creates a new instance of {{{CellDecoder}}} that uses the specified function to parse data. */
  def apply[A](f: String => Option[A]): CellDecoder[A] = new CellDecoder[A] {
    override def decode(a: String) =
      try { f(a) }
      catch { case _: Exception => None }
  }

  @inline private def toOpt[A](a: => A): Option[A] =
    try { Some(a) }
  catch { case _: Exception => None }

  implicit val string: CellDecoder[String]     = CellDecoder(s => Option(s))
  implicit val char:   CellDecoder[Char]       = CellDecoder(s => if(s.length == 1) Option(s(0)) else None)
  implicit val int   : CellDecoder[Int]        = CellDecoder(s => toOpt(s.toInt))
  implicit val float : CellDecoder[Float]      = CellDecoder(s => toOpt(s.toFloat))
  implicit val double: CellDecoder[Double]     = CellDecoder(s => toOpt(s.toDouble))
  implicit val long  : CellDecoder[Long]       = CellDecoder(s => toOpt(s.toLong))
  implicit val short : CellDecoder[Short]      = CellDecoder(s => toOpt(s.toShort))
  implicit val byte  : CellDecoder[Byte]       = CellDecoder(s => toOpt(s.toByte))
  implicit val bool  : CellDecoder[Boolean]    = CellDecoder(s => toOpt(s.toBoolean))
  implicit val bigInt: CellDecoder[BigInt]     = CellDecoder(s => toOpt(BigInt.apply(s)))
  implicit val bigDec: CellDecoder[BigDecimal] = CellDecoder(s => toOpt(BigDecimal.apply(s)))

  implicit def opt[A: CellDecoder]: CellDecoder[Option[A]] = CellDecoder { s =>
    if(s.isEmpty) Some(None)
    else          CellDecoder[A].decode(s).map(Option.apply)
  }

  implicit def either[A: CellDecoder, B: CellDecoder]: CellDecoder[Either[A, B]] =
    CellDecoder { s => CellDecoder[A].decode(s).map(a => Left(a): Either[A, B])
      .orElse(CellDecoder[B].decode(s).map(b => Right(b): Either[A, B]))
    }
}<commit_msg>Remove unnecessary double-protection against exceptions in standard cell decoders.<commit_after>package com.nrinaudo.csv

import simulacrum.{noop, typeclass}

/** Typeclass used to decode the content of a single CSV cell.
  *
  * Standard types are already provided for in the companion object.
  *
  * See also the companion class, {{{CellEncoder}}}, as well as {{{RowDecoder}}}, used to read wholes rows.
  */
@typeclass trait CellDecoder[A] {
  /** Turns the content of a CSV cell into an {{{A}}}. */
  @noop def decode(s: String): Option[A]

  @noop def decode(ss: Seq[String], index: Int): Option[A] =
    if(ss.isDefinedAt(index)) decode(ss(index))
    else                      None

  /** Creates a new {{{CellDecoder}}} that applies the specified function to the result of {{{read}}}.
    *
    * This can be useful if you just need a {{{CellDecoder}}} implementation that specialises an existing type - to add
    * a scalaz tag, say.
    */
  @noop def map[B](f: A => B): CellDecoder[B] = CellDecoder(s => decode(s).map(f))
}

/** Provides default implementations and construction methods for {{{CellDecoder}}}. */
object CellDecoder {
  /** Creates a new instance of {{{CellDecoder}}} that uses the specified function to parse data. */
  def apply[A](f: String => Option[A]): CellDecoder[A] = new CellDecoder[A] {
    override def decode(a: String) =
      try { f(a) }
      catch { case _: Exception => None }
  }

  implicit val string: CellDecoder[String]     = CellDecoder(s => Option(s))
  implicit val char:   CellDecoder[Char]       = CellDecoder(s => if(s.length == 1) Option(s(0)) else None)
  implicit val int   : CellDecoder[Int]        = CellDecoder(s => Option(s.toInt))
  implicit val float : CellDecoder[Float]      = CellDecoder(s => Option(s.toFloat))
  implicit val double: CellDecoder[Double]     = CellDecoder(s => Option(s.toDouble))
  implicit val long  : CellDecoder[Long]       = CellDecoder(s => Option(s.toLong))
  implicit val short : CellDecoder[Short]      = CellDecoder(s => Option(s.toShort))
  implicit val byte  : CellDecoder[Byte]       = CellDecoder(s => Option(s.toByte))
  implicit val bool  : CellDecoder[Boolean]    = CellDecoder(s => Option(s.toBoolean))
  implicit val bigInt: CellDecoder[BigInt]     = CellDecoder(s => Option(BigInt.apply(s)))
  implicit val bigDec: CellDecoder[BigDecimal] = CellDecoder(s => Option(BigDecimal.apply(s)))

  implicit def opt[A: CellDecoder]: CellDecoder[Option[A]] = CellDecoder { s =>
    if(s.isEmpty) Some(None)
    else          CellDecoder[A].decode(s).map(Option.apply)
  }

  implicit def either[A: CellDecoder, B: CellDecoder]: CellDecoder[Either[A, B]] =
    CellDecoder { s => CellDecoder[A].decode(s).map(a => Left(a): Either[A, B])
      .orElse(CellDecoder[B].decode(s).map(b => Right(b): Either[A, B]))
    }
}
{'fraction_non_alphanumeric': 0.1439929328621908, 'fraction_numerical': 0.0007067137809187279, 'mean_word_length': 3.6940298507462686, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1559101', 'n_tokens_mistral': 1789, 'n_tokens_neox': 1773, 'n_words': 528}