Usage

Dependency

sbt
libraryDependencies += "com.github.cerst" % "factories" % "0.2.0"
Maven
<dependency>
  <groupId>com.github.cerst</groupId>
  <artifactId>factories</artifactId>
  <version>0.2.0</version>
</dependency>
Gradle
dependencies {
  compile group: 'com.github.cerst', name: 'factories', version: '0.2.0'
}

Numeric Types (Double, Float, Int, Long, Short)

By default, implementations of the following operators are available for numeric types:

  • <
  • <=
  • >
  • >=

Example:

import com.github.cerst.factories.DefaultConstraints._
import com.github.cerst.factories._

object NumericExample {

  final case class PersonId(intValue: Int) extends AnyVal

  object PersonId {

    @throws[IllegalArgumentException]
    def apply(intValue: Int): PersonId = {
      // constraints are
      // - passed-in as varargs (i.e. you can specify 0 or more)
      // - evaluated in an '&&' fashion (i.e. the result is an error if and only if at least one constraint is violated)
      intValue.create(new PersonId(_), _ >= 0, _ <= 1024)
    }

    // there's also on overload to represent the error case using Either
    def apply2(intValue: Int): Either[String, PersonId] = {
      intValue.createEither(new PersonId(_), _ >= 0, _ <= 1024)
    }

  }

  def main(args: Array[String]): Unit = {
    println(PersonId.apply2(-1))
    // Left('-1' is not a valid 'PersonId' due to the following constraint violations: [ _ >= 0 ])

    println(PersonId(-1))
    // Exception in thread "main" java.lang.IllegalArgumentException: '-1' is not a valid 'PersonId' due to the following constraint violations: [ _ >= 0 ]
  }

}

String

By default, implementations of the following operators are available for strings:

  • _.length <
  • _.length <=
  • _.length >
  • _.length >=
  • matches

Example:

import com.github.cerst.factories.DefaultConstraints._
import com.github.cerst.factories._

import scala.util.matching.Regex

object StringExample {

  final case class IpV4Address(stringValue: String) extends AnyVal

  object IpV4Address {

    val regex: Regex = """\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}""".r

    def apply(string: String): IpV4Address = {
      // constraints are
      // - passed-in as varargs (i.e. you can specify 0 or more)
      // - evaluated in an '&&' fashion (i.e. the result is an error if and only if at least one constraint is violated)
      string.create(new IpV4Address(_), _.length >= 0, _ matches regex)
    }

    // there's also on overload to represent the error case as part of the return type
    def apply2(string: String): Either[String, IpV4Address] = {
      string.createEither(new IpV4Address(_), _ matches regex)
    }

  }

  def main(args: Array[String]): Unit = {
    println(IpV4Address.apply2("1234"))
    // Left('1234' is not a valid 'IpV4Address' due to the following constraint violations: [ _ matches \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} ])

    println(IpV4Address.apply("1234"))
    // Exception in thread "main" java.lang.IllegalArgumentException: '1234' is not a valid 'IpV4Address' due to the following constraint violations: [ _ matches \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} ]
  }

}

Selective Imports

In case you do not want to import all default constraint type class implementations, you can also do so selectively.
Simply check the traits mixed into DefaultConstraints which all come with a respective companion object.

The source code for this page can be found here.