Как определить dsl StopOnFirstFail для формы play2? - PullRequest
2 голосов
/ 18 марта 2012

В этом вопросе: Если в поле формы есть несколько валидаторов, как позволить play проверять их по одному, а не все? , Жюльен дал мне метод с именем stopOnFirstFail, чтобы решить мою проблему:

def stopOnFirstFail[T](constraints: Constraint[T]*) = Constraint { field: T =>
  constraints.toList dropWhile (_(field) == Valid) match {
    case Nil => Valid
    case constraint :: _ => constraint(field)
  }
}

Используется:

val loginForm = Form(
  "name" -> (text verifying stopOnFirstFail( nonEmpty, minLength(4) ))
)

Но я надеюсь определить dsl, который можно использовать как:

val loginForm = Form(
  "name" -> (text verifying ( nonEmpty or minLength(4) ))
)

Я пытался определить неявный метод для play.api.data.validation.Constraint:

import play.api.data.validation._

implicit def _Constraint[T](cons: Constraint[T]) = new {

  def or[T](other: Constraint[T]) = Constraint { field: T =>
    cons(field) match {              // (!)
      case Valid => other(field)
      case invalid => invlaid
    }
  }
}

Но он не может быть скомпилирован, ошибка в строке (!) И сообщение:

type mismatch; 
found: field.type (with underlying type T) required: T 
Note: implicit method _Constraint is not applicable here
      because it comes after the application point and it lacks an explicit result type

Как это исправить?

Ответы [ 2 ]

3 голосов
/ 18 марта 2012

Метод or не принимает параметр типа:

implicit def toLazyOr[T](cons: Constraint[T]) = new {
  def or(other: Constraint[T]) = Constraint { field: T =>
    cons(field) match {
      case Valid => other(field)
      case Invalid => Invalid
    }
  }
}
0 голосов
/ 04 марта 2013
  def stopOnFirstFail[T](constraints: Constraint[T]*) = Constraint { field: T =>
    var result: ValidationResult = null
    val loop = new Breaks
    loop.breakable(
      for (constrain <- constraints) {
        result = constrain(field)
        if (result != Valid) {
          loop.break()
        }
      }
    )
    if (result == null) Valid else result
  }

эта реализация выполняет проверки только один раз:)

...