PolicyK and Policy
Encapsulates Field validation logic.
type PolicyK[-A, F[_], V[_], E] = A => RuleK[F, V, E]
Syntaxβ
import fields._
import fields.value.FieldsDsl.default._
case class Email(value: String) extends AnyVal
object Email {
//Policy is interface with 1 validate method, so you can do so
implicit val policy: Policy[Email] = _.map(_.value).all(_.nonEmpty, _.maxSize(40))
}
case class Request(name: String, email: Email, age: Int, hasParrot: Boolean)
object Request {
implicit val policy: Policy[Request] =
Policy[Request]
.subRule(_.name)(_.minSize(4), _.maxSize(48)) //runs all validations combining using and
.subRule(_.email)(_.validate) //Reuse Email Policy
.subRule(_.age, _.hasParrot)((age, hasParrot) => age > 48 || (age > 22 && hasParrot.isTrue)) // 2 fields rule
}
Field(Request("", Email(""), 23, true)).validate.effect // This will use implicit policy to validate
// res1: List[ValidationMessage] = List(
// ValidationMessage(path = .name, error = "must have minimum size of 4"),
// ValidationMessage(path = .email, error = "must not be empty")
// )
Field(Request("1234", Email("ann@gmail.com"), 23, true)).validateEither
// res2: Either[List[ValidationMessage], Request] = Right(
// Request(
// name = "1234",
// email = Email("ann@gmail.com"),
// age = 23,
// hasParrot = true
// )
// )