|
| 1 | +package eu.timepit.refined |
| 2 | + |
| 3 | +import scala.annotation.compileTimeOnly |
| 4 | +import scala.compiletime.ops.int |
| 5 | +import scala.compiletime.ops.long |
| 6 | +import scala.compiletime.ops.string.CharAt |
| 7 | +import scala.compiletime.ops.string.Length |
| 8 | +import scala.compiletime.ops.string.Substring |
| 9 | +import scala.language.dynamics |
| 10 | + |
| 11 | +object W extends Dynamic { |
| 12 | + type StringTail[A <: String] = Substring[A, 1, Length[A]] |
| 13 | + |
| 14 | + type StringLast[A <: String] = CharAt[A, int.-[Length[A], 1]] |
| 15 | + |
| 16 | + type Literal[A <: String] = CharAt[A, 0] match { |
| 17 | + case '"' => |
| 18 | + // String |
| 19 | + StringLast[A] match { |
| 20 | + case '"' => |
| 21 | + Substring[A, 1, int.-[Length[A], 1]] |
| 22 | + } |
| 23 | + case '\'' => |
| 24 | + // Char |
| 25 | + CharAt[A, 2] match { |
| 26 | + case '\'' => |
| 27 | + Length[A] match { |
| 28 | + case 3 => |
| 29 | + CharAt[A, 1] |
| 30 | + } |
| 31 | + } |
| 32 | + case _ => |
| 33 | + // TODO support another types |
| 34 | + // e.g. Double, Float |
| 35 | + StringLast[A] match { |
| 36 | + case 'L' => |
| 37 | + // Long |
| 38 | + StringToLong[Substring[A, 0, int.-[Length[A], 1]]] |
| 39 | + case _ => |
| 40 | + // Int |
| 41 | + long.ToInt[StringToLong[A]] |
| 42 | + } |
| 43 | + } |
| 44 | + |
| 45 | + type StringToLong[Input <: String] <: Long = CharAt[Input, 0] match { |
| 46 | + case '-' => |
| 47 | + long.Negate[Loop[StringTail[Input], 0L]] |
| 48 | + case _ => |
| 49 | + Loop[Input, 0L] |
| 50 | + } |
| 51 | + |
| 52 | + type CharToLong[C <: Char] <: Long = C match { |
| 53 | + case '0' => 0L |
| 54 | + case '1' => 1L |
| 55 | + case '2' => 2L |
| 56 | + case '3' => 3L |
| 57 | + case '4' => 4L |
| 58 | + case '5' => 5L |
| 59 | + case '6' => 6L |
| 60 | + case '7' => 7L |
| 61 | + case '8' => 8L |
| 62 | + case '9' => 9L |
| 63 | + } |
| 64 | + |
| 65 | + type Loop[Input <: String, Acc <: Long] <: Long = Length[Input] match { |
| 66 | + case 0 => |
| 67 | + Acc |
| 68 | + case _ => |
| 69 | + Loop[ |
| 70 | + StringTail[Input], |
| 71 | + long.+[ |
| 72 | + long.*[10L, Acc], |
| 73 | + CharToLong[ |
| 74 | + CharAt[Input, 0] |
| 75 | + ] |
| 76 | + ] |
| 77 | + ] |
| 78 | + } |
| 79 | + |
| 80 | + @compileTimeOnly("Illegal reference") |
| 81 | + def selectDynamic( |
| 82 | + selector: String |
| 83 | + ): None.type { type T = Literal[selector.type] } = |
| 84 | + None.asInstanceOf[ |
| 85 | + None.type { type T = Literal[selector.type] } |
| 86 | + ] |
| 87 | +} |
0 commit comments