• Stars
    star
    434
  • Rank 100,274 (Top 2 %)
  • Language
    Scala
  • License
    Apache License 2.0
  • Created almost 4 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Strong type constraints for Scala

logo

Scala version support CI


Iron is a lightweight library for refined types in Scala 3.

It enables attaching constraints/assertions to types, to enforce properties and forbid invalid values.

  • Catch bugs. In the spirit of static typing, use more specific types to avoid invalid values.
  • Compile-time and runtime. Evaluate constraints at compile time, or explicitly check them at runtime (e.g. for a form).
  • Seamless. Iron types are subtypes of their unrefined versions, meaning you can easily add or remove them.
  • No black magic. Use Scala 3's powerful inline, types and restricted macros for consistent behaviour and rules. No unexpected behaviour.
  • Extendable. Easily create your own constraints or integrations using classic typeclasses.

To learn more about Iron, see the microsite.

Example

import io.github.iltotore.iron.*
import io.github.iltotore.iron.constraint.numeric.*

def log(x: Double :| Positive): Double =
  Math.log(x) //Used like a normal `Double`

log(1.0) //Automatically verified at compile time.
log(-1.0) //Compile-time error: Should be strictly positive

val runtimeValue: Double = ???
log(runtimeValue.refineUnsafe) //Explicitly refine your external values at runtime.

runtimeValue.refineEither.map(log) //Use monadic style for functional validation
runtimeValue.refineEither[Positive].map(log) //More explicitly

Helpful error messages

Iron provides useful errors when a constraint does not pass:

log(-1.0)
-- Constraint Error --------------------------------------------------------
Could not satisfy a constraint for type scala.Double.

Value: -1.0
Message: Should be strictly positive
----------------------------------------------------------------------------

Or when it cannot be verified:

val runtimeValue: Double = ???
log(runtimeValue)
-- Constraint Error --------------------------------------------------------
Cannot refine non full inlined input at compile-time.
To test a constraint at runtime, use the `refine` extension method.

Note: Due to a Scala limitation, already-refined types cannot be tested at compile-time (unless proven by an `Implication`).

Inlined input: runtimeValue
----------------------------------------------------------------------------

Import in your project

SBT:

libraryDependencies += "io.github.iltotore" %% "iron" % "version"

Mill:

ivy"io.github.iltotore::iron:version"

Note: replace version with the version of Iron.

Platform support

Module JVM JS Native
iron ✔️ ✔️ ✔️
iron-borer ✔️ ✔️
iron-cats ✔️ ✔️ ✔️
iron-circe ✔️ ✔️ ✔️
iron-ciris ✔️ ✔️ ✔️
iron-decline ✔️ ✔️ ✔️
iron-doobie ✔️
iron-jsoniter ✔️ ✔️ ✔️
iron-scalacheck ✔️ ✔️
iron-skunk ✔️ ✔️ ✔️
iron-upickle ✔️ ✔️ ✔️
iron-zio ✔️ ✔️
iron-zio-json ✔️ ✔️

Adopters

Here is a non-exhaustive list of projects using Iron.

Submit a PR to add your project or company to the list.

Useful links