Robots is a small Scala library which aims to provide helpful utilities for validating data using the type classes and data types provided by the Cats library.
Add the following to your build.sbt
:
libraryDependencies += "io.github.davidgregory084" %% "robots" % "0.1.0"
import robots.Validator, Validator._
import cats.data.Validated
import cats.instances.either._
import cats.instances.list._
import cats.instances.int._
case class Document(maxColumn: Int, maxLines: Int, lines: List[String])
val passing = Document(80, 120, List("Hello", "World"))
val failing = Document(4, 1, List("Hey", "World"))
val documentValidator =
validate[List, String, Document].
has(_.maxColumn)(gt(0, List("Max width should be greater than zero"))).
has(_.maxLines)(gt(0, List("Max line count should be greater than zero"))).
has2(_.maxLines, _.lines)(Validator {
case (maxLines, lines) =>
if (lines.length <= maxLines)
Nil
else
List("Exceeded the maximum number of lines")
}).
all2(_.maxColumn, _.lines)(Validator {
case (maxColumn, line) =>
if (line.length <= maxColumn)
Nil
else
List("Exceeded the maximum number of columns")
})
// Works well with `Either` and `Validated`
documentValidator.runNel[Validated](passing)
// res4: cats.data.Validated[cats.data.NonEmptyList[String],Document] = Valid(Document(80,120,List(Hello, World)))
documentValidator.runNel[Validated](failing)
// res5: cats.data.Validated[cats.data.NonEmptyList[String],Document] = Invalid(NonEmptyList(Exceeded the maximum number of lines, Exceeded the maximum number of columns))
documentValidator.runNel[Either](passing)
// res6: Either[cats.data.NonEmptyList[String],Document] = Right(Document(80,120,List(Hello, World)))
documentValidator.runNel[Either](failing)
// res7: Either[cats.data.NonEmptyList[String],Document] = Left(NonEmptyList(Exceeded the maximum number of lines, Exceeded the maximum number of columns))
// You can brjng any `MonadError`
import cats.data.Ior
// import cats.data.Ior
documentValidator.run[Ior[List[String], ?]](passing)
// res9: cats.data.Ior[List[String],Document] = Right(Document(80,120,List(Hello, World)))
documentValidator.run[Ior[List[String], ?]](failing)
// res10: cats.data.Ior[List[String],Document] = Left(List(Exceeded the maximum number of lines, Exceeded the maximum number of columns))
// Even ones that discard errors
import cats.instances.option._
// import cats.instances.option._
documentValidator.run_[Option](passing)
// res12: Option[Document] = Some(Document(80,120,List(Hello, World)))
documentValidator.run_[Option](failing)
// res13: Option[Document] = None
Contributors are expected to follow the Typelevel Code of Conduct while participating on Github and any other venues associated with the project.
Thanks to Dave Gurnell (@davegurnell) and Brendan Maginnis (@brendanator) for the design which inspired this library.
All code in this repository is licensed under the Apache License, Version 2.0. See LICENSE.