Skip to content

Instantly share code, notes, and snippets.

@deanwampler
Last active May 22, 2022 13:41
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save deanwampler/3a1c2b0ea9da7edf9f971b601d3a5eb2 to your computer and use it in GitHub Desktop.
// Adapted from "Programming Scala, Third Edition" (http://programming-scala.com)
// https://github.com/deanwampler/programming-scala-book-code-examples/blob/master/src/main/scala/progscala3/meta/Invariant.scala
import scala.quoted.*
object invariantDisabled:
inline val ignore = true
inline def apply[T](
inline predicate: Boolean,
inline message: String = "")(
inline block: T): T =
inline if !ignore then
if !predicate then fail(predicate, message, block, "before")
val result = block
if !predicate then fail(predicate, message, block, "after")
result
else
block
inline private def fail[T](
inline predicate: Boolean,
inline message: String,
inline block: T,
inline beforeAfter: String): Unit =
${ failImpl('predicate, 'message, 'block, 'beforeAfter) }
case class InvariantFailure(msg: String) extends RuntimeException(msg)
private def failImpl[T](
predicate: Expr[Boolean], message: Expr[String],
block: Expr[T], beforeAfter: Expr[String])(
using Quotes): Expr[String] =
'{ throw InvariantFailure(
s"""FAILURE! predicate "${${showExpr(predicate)}}" """
+ s"""failed ${$beforeAfter} evaluation of block:"""
+ s""" "${${showExpr(block)}}". Message = "${$message}". """)
}
private def showExpr[T](expr: Expr[T])(using Quotes): Expr[String] =
val code: String = expr.show
Expr(code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment