Skip to content

Commit

Permalink
feat: Allow both raw and refined types in RefinedTypeOps#apply (#261)
Browse files Browse the repository at this point in the history
  • Loading branch information
Iltotore authored Aug 29, 2024
1 parent 0257136 commit 8850124
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 6 deletions.
11 changes: 6 additions & 5 deletions main/src/io/github/iltotore/iron/RefinedTypeOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ trait RefinedTypeOps[A, C, T](using private val _rtc: RuntimeConstraint[A, C]):
* Implicitly refine at compile-time the given value.
*
* @param value the value to refine.
* @tparam A the refined type.
* @tparam C the constraint applied to the type.
* @return the given value typed as [[IronType]]
* @note This method ensures that the value satisfies the constraint. If it doesn't or isn't evaluable at compile-time, the compilation is aborted.
*/
inline def apply(value: A :| C): T = value.asInstanceOf[T]
inline def apply[A1 <: A](inline value: A1)(using inline constraint: Constraint[A, C]): T =
inline if macros.isIronType[A1, C] then value.asInstanceOf[T]
else
macros.assertCondition(value, constraint.test(value), constraint.message)
value.asInstanceOf[T]

/**
* Refine the given value, assuming the constraint holds.
Expand Down Expand Up @@ -176,4 +177,4 @@ object RefinedTypeOps:
* //FinalType =/= IronType
* }}}
*/
type FinalType = T
type FinalType = T
20 changes: 19 additions & 1 deletion main/src/io/github/iltotore/iron/macros/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package io.github.iltotore.iron.macros
import io.github.iltotore.iron.internal.{IronConfig, colorized}
import scala.Console.{MAGENTA, RESET}
import scala.quoted.*
import io.github.iltotore.iron.IronType
import io.github.iltotore.iron.Implication

/**
* Asserts at compile time if the given condition is true.
Expand Down Expand Up @@ -66,4 +68,20 @@ def compileTimeError(msg: String)(using Quotes): Nothing =
s"""|-- Constraint Error --------------------------------------------------------
|$msg
|----------------------------------------------------------------------------""".stripMargin
)
)

inline def isIronType[T, C]: Boolean = ${isIronTypeImpl[T, C]}
def isIronTypeImpl[T : Type, C : Type](using Quotes): Expr[Boolean] =
import quotes.reflect.*

val ironType = TypeRepr.of[IronType]
val implicationType = TypeRepr.of[Implication]
val targetConstraintType = TypeRepr.of[C]

TypeRepr.of[T] match
case AppliedType(tpe, List(baseType, constraintType)) if tpe =:= ironType =>
Implicits.search(implicationType.appliedTo(List(constraintType, targetConstraintType))) match
case _: ImplicitSearchSuccess => Expr(true)
case _: ImplicitSearchFailure => Expr(false)

case _ => Expr(false)

0 comments on commit 8850124

Please sign in to comment.