<commit_before>package kantan.xpath

import javax.xml.xpath.{XPathConstants, XPathExpression}

import scala.collection.generic.CanBuildFrom

class Expression private[xpath] (val expr: XPathExpression) {
  /** Finds the first node that matches the expression and evaluates it as an `A`. */
  def first[A: NodeDecoder](n: Node): DecodeResult[A] = Expression.first(n, expr)

  /** Finds all nodes matching the expression and evaluate them as an `F[A]]`, where `F` is a collection class. */
  def all[F[_], A](n: Node)(implicit da: NodeDecoder[A], cbf: CanBuildFrom[Nothing, DecodeResult[A], F[DecodeResult[A]]]): F[DecodeResult[A]] =
    Expression.all(n, expr)(da.decode)

  /** Turns this expression into an unsafe one
    *
    * An unsafe expression is one that throws exception when error occurs, as opposed to wrapping them in a
    * [[DecodeResult.Failure]].
    */
  def unsafe: UnsafeExpression = new UnsafeExpression(expr)

  def liftFirst[A: NodeDecoder]: (Node => DecodeResult[A]) = n => first(n)
  def liftAll[F[_], A: NodeDecoder](implicit cbf: CanBuildFrom[Nothing, DecodeResult[A], F[DecodeResult[A]]]): (Node => F[DecodeResult[A]]) =
    n => all(n)
}
<commit_msg>Add every method to Expression.<commit_after>package kantan.xpath

import javax.xml.xpath.{XPathConstants, XPathExpression}

import scala.annotation.tailrec
import scala.collection.generic.CanBuildFrom
import scala.collection.mutable

class Expression private[xpath] (val expr: XPathExpression) {
  /** Finds the first node that matches the expression and evaluates it as an `A`. */
  def first[A: NodeDecoder](n: Node): DecodeResult[A] = Expression.first(n, expr)

  /** Finds all nodes matching the expression and evaluate them as an `F[A]]`, where `F` is a collection class. */
  def all[F[_], A](n: Node)(implicit da: NodeDecoder[A], cbf: CanBuildFrom[Nothing, DecodeResult[A], F[DecodeResult[A]]]): F[DecodeResult[A]] =
    Expression.all(n, expr)(da.decode)

  def every[F[_], A](n: Node)(implicit da: NodeDecoder[A], cbf: CanBuildFrom[Nothing, A, F[A]]): DecodeResult[F[A]] = {
    val res = expr.evaluate(n, XPathConstants.NODESET).asInstanceOf[NodeList]

    @tailrec
    def loop(i: Int, acc: mutable.Builder[A, F[A]]): DecodeResult[F[A]] =
      if(i >= res.getLength) DecodeResult.success(acc.result())
      else da.decode(res.item(i)) match {
        case DecodeResult.Success(a) =>
          acc += a
          loop(i + 1, acc)
        case _ => DecodeResult.Failure
      }

    loop(0, cbf())
  }

  /** Turns this expression into an unsafe one
    *
    * An unsafe expression is one that throws exception when error occurs, as opposed to wrapping them in a
    * [[DecodeResult.Failure]].
    */
  def unsafe: UnsafeExpression = new UnsafeExpression(expr)

  def liftFirst[A: NodeDecoder]: (Node => DecodeResult[A]) = n => first(n)
  def liftAll[F[_], A: NodeDecoder](implicit cbf: CanBuildFrom[Nothing, DecodeResult[A], F[DecodeResult[A]]]): (Node => F[DecodeResult[A]]) =
    n => all(n)
}

{'fraction_non_alphanumeric': 0.14080267558528428, 'fraction_numerical': 0.0006688963210702341, 'mean_word_length': 4.36983842010772, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, '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': '5519915', 'n_tokens_mistral': 974, 'n_tokens_neox': 959, 'n_words': 278}