Skip to content

Instantly share code, notes, and snippets.

@Odomontois
Created April 11, 2025 09:14
Show Gist options
  • Save Odomontois/75a6971f550dc33eed272601807c37a8 to your computer and use it in GitHub Desktop.
Save Odomontois/75a6971f550dc33eed272601807c37a8 to your computer and use it in GitHub Desktop.
Case Insensitive Macro
import scala.quoted.{Expr, Quotes, Type}
object CI {
opaque type CI[p <: String] <: String = String
def unsafeConvert[s <: String, p <: String]: Conversion[s, CI[p]] = new Conversion[s, CI[p]] {
def apply(s: s): CI[p] = s
}
inline given [s <: String & Singleton, p <: String]: Conversion[s, CI[p]] = ${ convertImpl[s, p] }
private def convertImpl[s <: String: Type, p <: String: Type](using q: Quotes): Expr[Conversion[s, CI[p]]] = {
import q.reflect.*
def getConstant[s <: String: Type]: String =
TypeRepr.of[s] match
case ConstantType(StringConstant(str)) => str
case _ => report.errorAndAbort(s"Constant string expected, got ${Type.show[s]}")
val s = getConstant[s]
val p = getConstant[p]
if s.toLowerCase() == p.toLowerCase() then '{ CI.unsafeConvert[s, p] }
else report.errorAndAbort(s"String literal $s does not match $p")
}
}
export CI.CI
val h: CI["Hello"] = "heLlo"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment