Skip to content

Instantly share code, notes, and snippets.

@propensive
Forked from jto/Unwrap.scala
Created February 12, 2021 14:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save propensive/94ec18663a7535db45bb7e2ef37178ff to your computer and use it in GitHub Desktop.
Save propensive/94ec18663a7535db45bb7e2ef37178ff to your computer and use it in GitHub Desktop.
object Unpack:
import scala.quoted._
import scala.compiletime._
private def tupleType(s: String)(using q: Quotes): q.reflect.TypeRepr =
import q.reflect._
val typeParams =
s.map{ c =>
TypeRepr.of(using ConstantType(CharConstant(c)).asType)
}.toList
assert(typeParams.length > 0)
assert(typeParams.length < 23)
typeParams.length match
case 1 => typeParams.head
case l =>
TypeRepr.typeConstructorOf(Class.forName(s"scala.Tuple$l"))
.appliedTo(typeParams)
private def unpackImpl[S <: Singleton & String: Type](using q: Quotes): Expr[Any] =
import q.reflect._
TypeRepr.of[S] match
case ConstantType(StringConstant("")) =>
'{EmptyTuple}
case ConstantType(StringConstant(str)) =>
tupleType(str).asType match
case '[tpe] =>
'{ Tuple.fromArray(${Expr(str.toArray)}).asInstanceOf[tpe] }
transparent inline def unpack[T <: Singleton & String] =
${ unpackImpl[T] }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment