Skip to main content

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.

Stand With Ukraine

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.