I don't know how to put this in to words, so I'll throw it in an example..
case class AddressInput(house: Option[Int], street: Option[String], street2: Option[String])
case class ValidatedAddress(house: Int, street: String, street2: Option[String])
implicit val checkAddress: Rule[AddressInput, ValidatedAddress]
Rule[AddressInput]
.field(_.house)(req andThen gte(1))
.field(_.street)(req andThen trimString andThen nonEmpty)
.field(_.street2)(optional(trimString))
.map { addr =>
ValidatedAddress(addr.house.get, addr.street.get, addr.street2.get
}
Having to use .get in there is pretty unfortunate. If instead running .field would return some sort of RuleBuilder[A, B] where A is the input type, and B is the output type, you could do something like
case class AddressInput(house: Option[Int], street: Option[String], street2: Option[String])
case class ValidatedAddress(house: Int, street: String, street2: Option[String])
implicit val checkAddress: Rule[AddressInput, ValidatedAddress]
Rule[AddressInput]
.field(_.house)(req andThen gte(1)) // RuleBuilder[AddressInput, Int :: HNil]
.field(_.street)(req andThen trimString andThen nonEmpty) // RuleBuilder[AddressInput, Int :: String :: HNil]
.field(_.street2)(optional(trimString)) // RuleBuilder[AddressInput, Int :: String :: Option[String] :: HNil]
.build {
case street2 :: street :: house :: HNil => ValidatedAddress(street2, street, house)
}
This could be expanded upon and you could have the builder function derived from shapeless Generic as well. When working with scalapb especially this feature would be useful. A builder which just returns a Rule[A, A] would also be possible, but I think that the Rule class itself should have a method for running a sanitization and returning the validated (and unsanitized) result.
I'll consider making a PR as a POC sometime soon if I can find time.
I don't know how to put this in to words, so I'll throw it in an example..
Having to use
.get
in there is pretty unfortunate. If instead running.field
would return some sort ofRuleBuilder[A, B]
whereA
is the input type, andB
is the output type, you could do something likeThis could be expanded upon and you could have the builder function derived from shapeless
Generic
as well. When working withscalapb
especially this feature would be useful. A builder which just returns aRule[A, A]
would also be possible, but I think that theRule
class itself should have a method for running a sanitization and returning the validated (and unsanitized) result.I'll consider making a PR as a POC sometime soon if I can find time.