Skip to content

Commit

Permalink
feat: Add short-form messages
Browse files Browse the repository at this point in the history
  • Loading branch information
Iltotore committed Jun 20, 2024
1 parent 3b05871 commit c822d78
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 14 deletions.
13 changes: 11 additions & 2 deletions main/src/io/github/iltotore/iron/internal/IronConfig.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
package io.github.iltotore.iron.internal

case class IronConfig(color: Boolean, oneLine: Boolean)
/**
* The config or Iron at compile-time.
*
* @param color enable colored messages
* @param shortMessages use abbreviated messages, useful for error lenses and similar
*/
case class IronConfig(color: Boolean, shortMessages: Boolean)

object IronConfig:

/**
* The config as defined by the properties/environment.
*/
val fromSystem: IronConfig = IronConfig(
color = sys.props.get("iron.color").orElse(sys.env.get("IRON_COLOR")).flatMap(_.toBooleanOption).getOrElse(true),
oneLine = sys.props.get("iron.oneLine").orElse(sys.env.get("IRON_ONE_LINE")).flatMap(_.toBooleanOption).getOrElse(false),
shortMessages = sys.props.get("iron.shortMessages").orElse(sys.env.get("IRON_SHORT_MESSAGES")).flatMap(_.toBooleanOption).getOrElse(false),
)
32 changes: 20 additions & 12 deletions main/src/io/github/iltotore/iron/macros/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,12 @@ private def assertConditionImpl[A: Type](input: Expr[A], cond: Expr[Boolean], me
val inputType = TypeRepr.of[A]

val messageValue = message.decode.getOrElse("<Unknown message>")
val condValue = cond.decode
.fold(
err => compileTimeError(

def condError(failure: DecodingFailure): Nothing =
if config.shortMessages then
report.errorAndAbort("Cannot refine value at compile-time.")
else
compileTimeError(
s"""Cannot refine value at compile-time because the predicate cannot be evaluated.
|This is likely because the condition or the input value isn't fully inlined.
|
Expand All @@ -41,21 +44,26 @@ private def assertConditionImpl[A: Type](input: Expr[A], cond: Expr[Boolean], me
|${"Inlined input".colorized(MAGENTA)}: ${input.asTerm.show}
|${"Inlined condition".colorized(MAGENTA)}: ${cond.asTerm.show}
|${"Message".colorized(MAGENTA)}: $messageValue
|${"Reason".colorized(MAGENTA)}: ${err.prettyPrint()}""".stripMargin
),
identity
)
|${"Reason".colorized(MAGENTA)}: ${failure.prettyPrint()}""".stripMargin
)

val inputValue = input.decode.toOption
val condValue = cond.decode.fold(condError, identity)

if !condValue then
compileTimeError(s"""|Could not satisfy a constraint for type ${inputType.show.colorized(MAGENTA)}.
|
|${"Value".colorized(MAGENTA)}: ${input.asTerm.show}
|${"Message".colorized(MAGENTA)}: $messageValue""".stripMargin)
if config.shortMessages then
report.errorAndAbort(s"$messageValue: ${inputValue.getOrElse(input.show)}")
else
compileTimeError(s"""|Could not satisfy a constraint for type ${inputType.show.colorized(MAGENTA)}.
|
|${"Value".colorized(MAGENTA)}: ${inputValue.getOrElse(input.show)}
|${"Message".colorized(MAGENTA)}: $messageValue""".stripMargin)

'{}

def compileTimeError(msg: String)(using Quotes): Nothing =
quotes.reflect.report.errorAndAbort(
s"""|-- Constraint Error --------------------------------------------------------
|$msg
|----------------------------------------------------------------------------""".stripMargin
)
)

0 comments on commit c822d78

Please sign in to comment.