Valar
0.6.0Type-safe validation for Scala 3
A validation library for Scala 3 that derives validators from your types at compile time. The derivation uses inline macros and Mirror types to inspect case classes and generate validation code through the type system. If a field type is missing a validator, the compiler reports every missing one, names the fields, and tells you what to add. Validators compose in two modes: zip to collect all errors in one pass, flatMap to stop at the first. Errors are structured with field paths, so a failure in a nested object points to the exact location. Cross-compiles to JVM and Scala Native.
Examples
Validators compose — zip collects all errors in one pass
val user = (
field("name", nonEmpty),
field("age", between(0, 150)),
field("email", matches(emailPattern))
).zip // collects all errors in one pass
user.validate(input)Compile-time derivation from case classes
case class Config(host: String, port: Int, debug: Boolean)
// Valar derives the validator from the type at compile time.
// Missing validators cause a compile error, not a runtime one.
val validator = Validator.derived[Config]Structured errors with field paths
val result = user.validate(badInput)
// Left(List(
// ValidationError("name", "must not be empty"),
// ValidationError("age", "must be between 0 and 150"),
// ValidationError("email", "must match pattern")
// ))Fail-fast with flatMap, accumulate with zip
// Stop at the first error
val strict = nameV.flatMap(_ => ageV).flatMap(_ => emailV)
// Collect all errors in one pass
val lenient = (nameV, ageV, emailV).zipCross-compiles to JVM and Scala Native
// build.sbt
lazy val core = crossProject(JVMPlatform, NativePlatform)
.settings(
name := "valar-core",
libraryDependencies += "net.ghoula" %%% "valar-core" % "0.6.0"
)