diff --git a/build.sbt b/build.sbt index 40369e8..c9d097f 100644 --- a/build.sbt +++ b/build.sbt @@ -20,8 +20,8 @@ ThisBuild / developers := ) lazy val V = new { - val Cats = "2.7.0" - val Zio = "1.0.13" + val Cats = "2.8.0" + val Zio = "1.0.15" val Scala3 = "3.1.2" val Scala213 = "2.13.8" val Scala212 = "2.12.16" diff --git a/examples/src/main/scala/examples/RegisterExample.scala b/examples/src/main/scala/examples/RegisterExample.scala index 8a2182e..ef27437 100644 --- a/examples/src/main/scala/examples/RegisterExample.scala +++ b/examples/src/main/scala/examples/RegisterExample.scala @@ -88,9 +88,8 @@ object RegisterRequest { def asyncPolicy(implicit userService: UserService): Policy[RegisterRequest] = Policy .builder[RegisterRequest] - // Include Basic validation - .rule(RegisterRequest.basicPolicy.validate) // Below will work to but keep in mind not to fall for cyclic implicit resolution + // .rule(RegisterRequest.basicPolicy) // .rule(_.validate) // Our Async validations .subRule(_.username)( @@ -99,6 +98,7 @@ object RegisterRequest { ) .subRule(_.email)(_.ensureF(userService.emailIsAvailable, _.failMessage("Email is not available"))) .build + .and(RegisterRequest.basicPolicy) } trait UserService { diff --git a/examples/src/main/scala/examples/medium/MediumExample.scala b/examples/src/main/scala/examples/medium/MediumExample.scala index 4a9cd97..2dd9ea6 100644 --- a/examples/src/main/scala/examples/medium/MediumExample.scala +++ b/examples/src/main/scala/examples/medium/MediumExample.scala @@ -39,7 +39,7 @@ case class PostValidationService(postRepo: PostRepo, userRepo: UserRepo) { implicit val policy: Policy[MediumPost] = Policy .builder[MediumPost] - .rule(MediumPost.policy.validate) + .rule(MediumPost.policy) .subRule(_.authorId)(_.ensureF(userRepo.userExists, failCode(33))) .subRule(_.postId)(_.ensureF(postRepo.postDoesNotExist, failCode(44))) .subRule(_.title)(_.ensureF(postRepo.titleExists(_).negate, failCode(55))) diff --git a/modules/core/src/main/scala/fields/ValidationPolicy.scala b/modules/core/src/main/scala/fields/ValidationPolicy.scala index dff3c55..4430364 100644 --- a/modules/core/src/main/scala/fields/ValidationPolicy.scala +++ b/modules/core/src/main/scala/fields/ValidationPolicy.scala @@ -19,7 +19,7 @@ package jap.fields import typeclass._ /** Typeclass that defines how to validate given field */ -trait ValidationPolicy[P, F[_], V[_], E] { self => +trait ValidationPolicy[P, F[_], V[_], E] extends (Field[P] => Rule[F, V, E]) { self => def validate(field: Field[P]): Rule[F, V, E] def apply(field: Field[P]): Rule[F, V, E] = validate(field) @@ -30,6 +30,12 @@ trait ValidationPolicy[P, F[_], V[_], E] { self => if (V.isValid(v)) Right(field.value) else Left(E.errors(v)) } + + def and(other: ValidationPolicy[P, F, V, E])(implicit F: Effect[F], V: Validated[V]): ValidationPolicy[P, F, V, E] = + field => Rule.and(self(field), other(field)) + + def or(other: ValidationPolicy[P, F, V, E])(implicit F: Effect[F], V: Validated[V]): ValidationPolicy[P, F, V, E] = + field => Rule.or(self(field), other(field)) } object ValidationPolicy {