Skip to content

Instantly share code, notes, and snippets.

@xuwei-k
Last active January 27, 2024 10:40
Show Gist options
  • Save xuwei-k/adbb9e6caeaf2eb73214f1e10f50bc44 to your computer and use it in GitHub Desktop.
Save xuwei-k/adbb9e6caeaf2eb73214f1e10f50bc44 to your computer and use it in GitHub Desktop.
shapeless.Witness match type
import scala.compiletime.ops.string.Length
import scala.compiletime.ops.string.CharAt
import scala.compiletime.ops.string.Substring
import scala.compiletime.ops.int
import scala.compiletime.ops.long
import scala.language.dynamics
object Witness extends Dynamic {
type StringTail[A <: String] = Substring[A, 1, Length[A]]
type StringLast[A <: String] = CharAt[A, int.-[Length[A], 1]]
type Literal[A <: String] = CharAt[A, 0] match {
case '"' =>
StringLast[A] match {
case '"' =>
Substring[A, 1, int.-[Length[A], 1]]
}
case '\'' =>
CharAt[A, 2] match {
case '\'' =>
Length[A] match {
case 3 =>
CharAt[A, 1]
}
}
case _ =>
StringLast[A] match {
case 'L' =>
StringToLong[Substring[A, 0, int.-[Length[A], 1]]]
case _ =>
long.ToInt[StringToLong[A]]
}
}
type StringToLong[Input <: String] <: Long = CharAt[Input, 0] match {
case '-' =>
long.Negate[Loop[StringTail[Input], 0L]]
case _ =>
Loop[Input, 0L]
}
type CharToLong[C <: Char] <: Long = C match {
case '0' => 0L
case '1' => 1L
case '2' => 2L
case '3' => 3L
case '4' => 4L
case '5' => 5L
case '6' => 6L
case '7' => 7L
case '8' => 8L
case '9' => 9L
}
type Loop[Input <: String, Acc <: Long] <: Long = Length[Input] match {
case 0 =>
Acc
case _ =>
Loop[
StringTail[Input],
long.+[
long.*[10L, Acc],
CharToLong[
CharAt[Input, 0]
]
]
]
}
def selectDynamic(
selector: String
): None.type { type T = Literal[selector.type] } =
None.asInstanceOf[
None.type { type T = Literal[selector.type] }
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment