<commit_before>package org.supler.validation

import org.json4s.JField
import org.json4s.JsonAST.JInt
import org.supler.Message

trait Validator[T, U] {
  def doValidate(objValue: T, fieldValue: U): List[Message]
  def generateJSON: List[JField]
}

trait Validators {
  def minLength[T](minLength: Int) =
    fieldValidator[T, String](_.length < minLength)(_ => Message("error_length_tooShort", minLength))(List(JField("min_length", JInt(minLength))))

  def maxLength[T](maxLength: Int) =
    fieldValidator[T, String](_.length > maxLength)(_ => Message("error_length_tooLong", maxLength))(List(JField("max_length", JInt(maxLength))))

  def gt[T](than: Int) =
    fieldValidator[T, Int](_ <= than)(_ => Message("error_number_gt", than))(
      List(JField("gt", JInt(than))))

  def lt[T](than: Int) =
    fieldValidator[T, Int](_ >= than)(_ => Message("error_number_lt", than))(
      List(JField("lt", JInt(than))))

  def ge[T](than: Int) =
    fieldValidator[T, Int](_ < than)(_ => Message("error_number_ge", than))(
      List(JField("ge", JInt(than))))

  def le[T](than: Int) =
    fieldValidator[T, Int](_ > than)(_ => Message("error_number_le", than))(
      List(JField("le", JInt(than))))

  def ifDefined[T, U](v: Validator[T, U]): Validator[T, Option[U]] =
    new Validator[T, Option[U]] {
      override def doValidate(objValue: T, fieldValue: Option[U]) =
        fieldValue.map(v.doValidate(objValue, _)).getOrElse(Nil)
      override def generateJSON = v.generateJSON
    }

  def custom[T, U](errorTest: (T, U) => Boolean, createError: (T, U) => Message): Validator[T, U] = new Validator[T, U] {
    override def doValidate(objValue: T, fieldValue: U) = {
      if (errorTest(objValue, fieldValue)) {
        List(createError(objValue, fieldValue))
      } else {
        Nil
      }
    }
    override def generateJSON = Nil
  }

  private def fieldValidator[T, U](errorTest: U => Boolean)(createError: U => Message)(json: List[JField]) =<commit_msg>It only makes sense for a validator to serialize to json as a single field or none<commit_after>package org.supler.validation

import org.json4s.JField
import org.json4s.JsonAST.JInt
import org.supler.Message

trait Validator[T, U] {
  def doValidate(objValue: T, fieldValue: U): List[Message]
  def generateJSON: Option[JField]
}

trait Validators {
  def minLength[T](minLength: Int) =
    fieldValidator[T, String](_.length < minLength)(_ => Message("error_length_tooShort", minLength))(Some(JField("min_length", JInt(minLength))))

  def maxLength[T](maxLength: Int) =
    fieldValidator[T, String](_.length > maxLength)(_ => Message("error_length_tooLong", maxLength))(Some(JField("max_length", JInt(maxLength))))

  def gt[T](than: Int) =
    fieldValidator[T, Int](_ <= than)(_ => Message("error_number_gt", than))(
      Some(JField("gt", JInt(than))))

  def lt[T](than: Int) =
    fieldValidator[T, Int](_ >= than)(_ => Message("error_number_lt", than))(
      Some(JField("lt", JInt(than))))

  def ge[T](than: Int) =
    fieldValidator[T, Int](_ < than)(_ => Message("error_number_ge", than))(
      Some(JField("ge", JInt(than))))

  def le[T](than: Int) =
    fieldValidator[T, Int](_ > than)(_ => Message("error_number_le", than))(
      Some(JField("le", JInt(than))))

  def ifDefined[T, U](v: Validator[T, U]): Validator[T, Option[U]] =
    new Validator[T, Option[U]] {
      override def doValidate(objValue: T, fieldValue: Option[U]) =
        fieldValue.map(v.doValidate(objValue, _)).getOrElse(Nil)
      override def generateJSON = v.generateJSON
    }

  def custom[T, U](errorTest: (T, U) => Boolean, createError: (T, U) => Message): Validator[T, U] = new Validator[T, U] {
    override def doValidate(objValue: T, fieldValue: U) = {
      if (errorTest(objValue, fieldValue)) {
        List(createError(objValue, fieldValue))
      } else {
        Nil
      }
    }
    override def generateJSON = None
  }

  private def fieldValidator[T, U](errorTest: U => Boolean)(createError: U => Message)(json: Some[JField]) =
{'fraction_non_alphanumeric': 0.16832669322709162, 'fraction_numerical': 0.00099601593625498, 'mean_word_length': 4.510288065843621, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 29, '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': '3313360', 'n_tokens_mistral': 1396, 'n_tokens_neox': 1382, 'n_words': 302}