How to define a StopOnFirstFail dsl for play2's form?

隐身守侯 提交于 2019-12-31 02:55:38

问题


In this question: If a form field has multi validators, how to let play verify them one by one, not all?, Julien gave me a method named stopOnFirstFail to solve my problem:

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

It's usage is:

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

But I hope to define a dsl which can be used as:

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

I tried to defined an implicit method for 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
    }
  }
}

But it can't be compiled, the error in on the (!) line, and message is:

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

How to fix it?


回答1:


The or method does not take a type parameter:

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



回答2:


  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
  }

this implementations makes validations just once :)



来源:https://stackoverflow.com/questions/9759660/how-to-define-a-stoponfirstfail-dsl-for-play2s-form

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!