Overview
Fields is a Scala validation library that you should use because it is:
- Final Tagless. Choose any Effect, Validated, or Error types.
- Informative. Error paths help understanding where the error occurred.
- Expressive. Rich, extendable validation syntax.
- Lightweight. The core module has no-dependencies.
- Dauntless. Have no fear of complex validations with
Rule
type. - Short-circuit. Avoid running undesired validation side-effects.
Getting startedβ
To get started with sbt, simply add the following line to your build.sbt
file.
libraryDependencies ++= List(
"company.jap" %% "fields-core" % "0.4.16",
"company.jap" %% "fields-zio" % "0.4.16",
"company.jap" %% "fields-cats" % "0.4.16",
)
Code teaserβ
import jap.fields._
import jap.fields.DefaultAccumulateVM._
case class User(username: String, password: String, passwordRepeat: Option[String])
case class UserFeatures(standsWithUkraine: Boolean)
case class Request(user: User, features: UserFeatures)
object Request {
implicit val policy: Policy[Request] =
Policy
.builder[Request]
.subRule(_.user.username)(_.nonBlank, _.minSize(4))
.subRule(_.user.password)(_.nonBlank, _.minSize(8), _.maxSize(30))
.subRule(_.user.password, _.user.passwordRepeat)((p, pr) => pr.some(_ === p))
.rule { request =>
val standsWithUkraineF = request.sub(_.features.standsWithUkraine)
standsWithUkraineF.ensure(_ == true, _.failMessage("https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md"))
}
.build
}
val request = Request(User("Ann", "1234", Some("")), UserFeatures(false))
// request: Request = Request(
// user = User(
// username = "Ann",
// password = "1234",
// passwordRepeat = Some(value = "")
// ),
// features = UserFeatures(standsWithUkraine = false)
// )
Field(request).validate
// res0: Rule[Sync, [E >: Nothing <: Any] => Accumulate[E], ValidationError] = Invalid(
// errors = List(
// MinSize(
// path = FieldPath(
// parts = List(Path(value = "user"), Path(value = "username"))
// ),
// size = 4
// ),
// MinSize(
// path = FieldPath(
// parts = List(Path(value = "user"), Path(value = "password"))
// ),
// size = 8
// ),
// Equal(
// path = FieldPath(
// parts = List(Path(value = "user"), Path(value = "passwordRepeat"))
// ),
// compared = ".user.password"
// ),
// Message(
// path = FieldPath(
// parts = List(
// Path(value = "features"),
// Path(value = "standsWithUkraine")
// )
// ),
// error = "https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md",
// message = None
// )
// )
// )
This is just the basics of Fields, but there is still plenty of syntax to learn, see other Documentation sections.
Adoptersβ
Is your company using Fields and want to be listed here?
We will be happy to feature your company here, but in order to do that, we'll need written permission to avoid any legal misunderstandings.
Please open new Github Issue and provide us with your company name, logo and legal permission to add your company as.
Sponsorsβ
Development and maintenance of Fields is sponsored by Jap
Licenseβ
Licensed under the Apache License 2.0. Refer to the license file.