Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added new methods for Validation #624

Merged
merged 5 commits into from
Jan 12, 2024
Merged

Conversation

pablf
Copy link
Member

@pablf pablf commented Dec 24, 2023

Add methods to create Validations for Option and Either types. It also allows to create new validations with method premap. Adresses #588.
Use:

case class User(
  @validate(Validation.email.optional()) // same as @validate(Validation.email.optional(true))
  email: Option[String] // can be empty and still pass validation
)
case class User(
  @validate(Validation.email.optional(false))
  email: Option[String] // doesn't pass validation when empty
)

@pablf pablf requested a review from a team as a code owner December 24, 2023 12:14
@@ -4,6 +4,13 @@ sealed trait Bool[A] { self =>
def &&(that: Bool[A]): Bool[A] = Bool.And(self, that)
def ||(that: Bool[A]): Bool[A] = Bool.Or(self, that)
def unary_! : Bool[A] = Bool.Not(self)

def map[B](f: A => B, notCounter: Int = 0): Bool[B] = self match {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This notCounter parameter is not used for anything

type Errors = Chunk[ValidationError]
type Result = Either[Errors, Errors]
def validate(value: A): Result
def premap[B](f: B => A): Predicate[B] = Predicate.Premap(Bool.Leaf(self), f)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this called contramap?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you are right! Fixed this and the counter.

}
}

final case class Contramap[B, A](pred: Bool[Predicate[A]], f: (B => A)) extends Predicate[B] {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Storing a Scala function inside Contramap may complicate the story of converting a validation into a JSON Spec. Is contramap strictly required?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really, but I think that using typeclasses and implicits can solve that while allowing for composability and customization. Some libraries also allow for a custom validation, which might be a nice addition in this direction. What do you think?

@jdegoes jdegoes merged commit bc32646 into zio:main Jan 12, 2024
13 checks passed
@pablf pablf deleted the validation-methods branch January 23, 2024 10:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants