Skip to content

rparree/iron

 
 

Repository files navigation

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.refine) //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-cats ✔️ ✔️ ✔️
iron-circe ✔️ ✔️ ✔️
iron-jsoniter ✔️ ✔️ ✔️
iron-scalacheck ✔️ ✔️
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

About

Strong type constraints for Scala

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Scala 93.8%
  • Shell 3.6%
  • Batchfile 2.6%