octopus icon indicating copy to clipboard operation
octopus copied to clipboard

How to validate a collection of primitives?

Open rfuerst87 opened this issue 4 years ago • 3 comments

I'm stuck trying to validate the following case class:

final case class Post(
    tags: Seq[String]
)

For instance I must ensure no element in tags contains an empty string. For case classes it's obvious to just bring a corresponding validator into scope. But how does this work for primitive types? I cannot just write a Validator[String] because then this validator would be applied to all Strings, right? Or maybe I'm completely on the wrong track...

rfuerst87 avatar Oct 31 '19 08:10 rfuerst87

Hi @rfuerst87.

Yes, your assumption about defining validator on String is correct - it would be applied to all strings, to that's not the best idea.

But you can do the following:

  1. define separate value class case class Tag(value: String) extends AnyVal and define a validator for Tag type (usign ruleVC) specifying that the value must not be empty.
  2. define a rule for the Post type .rule(_.tags.forall(_.nonEmpty), "...") that checks all the sequence values at once.

With 1) you will have precise error messages, specifying which element of collection was empty, while with 2) your message will not be so detailed.

Hope it helps.

krzemin avatar Oct 31 '19 09:10 krzemin

Hi @krzemin

Thank you for your quick reply. Would it be possible to extend the rule api in a way, that you can explicitly pass a validator for a selector? Something like

val tagValidator = Validator[String].rule(...)
implicit val postValidator = Validator[Post].rule(_.tags, tagValidator, "...")

IMHO this would make a nice feature for octopus. That way you can have detailed error messages without having to introduce value classes for primitive types.

rfuerst87 avatar Oct 31 '19 12:10 rfuerst87

Sure, sounds good 👍 PRs welcome.

krzemin avatar Apr 11 '20 12:04 krzemin