Created
April 22, 2021 04:08
-
-
Save rssh/49d0e05dcd27678417a18248a114930e to your computer and use it in GitHub Desktop.
dn-q: ShowLabel
This file contains 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
val dottyVersion = "3.0.0-RC3" | |
lazy val root = project | |
.in(file(".")) | |
.settings( | |
name := "test", | |
version := "0.0.1", | |
scalaVersion := dottyVersion, | |
scalacOptions ++= Seq( "-unchecked", "-Ycheck:macros" ), | |
) | |
This file contains 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
// in src/main/scala/x | |
package x | |
// should pass compile | |
case class TestMappingTemplate() derives ShowName { | |
//... | |
} | |
// should fail on compile | |
case class SomeOtherThing() derives ShowName { | |
// ... | |
} | |
object Run extends App: | |
println("run") | |
This file contains 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
// in src/main/scala/x | |
package x | |
import scala.deriving._ | |
import scala.compiletime._ | |
import scala.quoted.* | |
object ShowLabel { | |
def showLabelExpr[T](label: Expr[String])(using Quotes)(using Type[T]): Expr[ShowName[T]] = { | |
val docRegex = "(Test)(Mapping)([a-zA-Z]+)".r | |
val simpleRegex = "([a-zA-Z]+)(Mapping)([a-zA-Z]+)".r | |
given ToExpr[ShowName[T]] with { | |
override def apply(x: ShowName[T])(using Quotes): Expr[ShowName[T]] = | |
Expr.summon[ShowName[T]].get | |
} | |
label.value match { | |
case Some(docRegex(doc, _, _)) => | |
Expr( | |
new ShowName[T] { | |
def name(source: Option[String]): String = | |
s"$doc".toLowerCase | |
} | |
) | |
case Some(simpleRegex(docType, _, _)) => | |
Expr( | |
new ShowName[T] { | |
def name(source: Option[String]): String = | |
s"$docType".toLowerCase | |
} | |
) | |
case Some(value) => | |
quotes.reflect.report.throwError(s"Can't produce such name: $value") | |
case None => | |
quotes.reflect.report.throwError(s"Expected label to be a known string but was: ${label.show}") | |
} | |
} | |
} |
This file contains 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
// in src/main/scala/x | |
package x | |
import scala.deriving._ | |
import scala.compiletime._ | |
import scala.quoted.* | |
trait ShowName[T] { | |
def name(source: Option[String]): String | |
} | |
object ShowName { | |
// you need helper because you can't pass '{m.MirroredLabel} directly | |
inline def _helper[T](inline label: String): ShowName[T] = | |
${ ShowLabel.showLabelExpr[T]('label) } | |
inline given derived[T](using m: Mirror.Of[T]): ShowName[T] = | |
_helper[T](constValue[m.MirroredLabel]) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you for reply. It really works with compile check but the
name
method won't work if you try to use it:It just runs the app forever without error or output.