Last active
May 22, 2022 13:29
-
-
Save deanwampler/466e8ce52ae21b48a0fb8c60aa595076 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 invariantEnabled: | |
inline val ignore = false | |
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